home *** CD-ROM | disk | FTP | other *** search
/ Enter 2004 April / enter-2004-04.iso / files / httrack-3.30.exe / {app} / src / htscoremain.c < prev    next >
Encoding:
C/C++ Source or Header  |  2003-10-11  |  87.8 KB  |  2,353 lines

  1. /* ------------------------------------------------------------ */
  2. /*
  3. HTTrack Website Copier, Offline Browser for Windows and Unix
  4. Copyright (C) Xavier Roche and other contributors
  5.  
  6. This program is free software; you can redistribute it and/or
  7. modify it under the terms of the GNU General Public License
  8. as published by the Free Software Foundation; either version 2
  9. of the License, or any later version.
  10.  
  11. This program is distributed in the hope that it will be useful,
  12. but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14. GNU General Public License for more details.
  15.  
  16. You should have received a copy of the GNU General Public License
  17. along with this program; if not, write to the Free Software
  18. Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  19.  
  20.  
  21. Important notes:
  22.  
  23. - We hereby ask people using this source NOT to use it in purpose of grabbing
  24. emails addresses, or collecting any other private information on persons.
  25. This would disgrace our work, and spoil the many hours we spent on it.
  26.  
  27.  
  28. Please visit our Website: http://www.httrack.com
  29. */
  30.  
  31.  
  32. /* ------------------------------------------------------------ */
  33. /* File: httrack.c subroutines:                                 */
  34. /*       main routine (first called)                            */
  35. /* Author: Xavier Roche                                         */
  36. /* ------------------------------------------------------------ */
  37.  
  38. #include "htscoremain.h"
  39.  
  40. #include "htsglobal.h"
  41. #include "htscore.h"
  42. #include "htsdefines.h"
  43. #include "htsalias.h"
  44. #include "htswrap.h"
  45. #include "htsmodules.h"
  46.  
  47. #include <ctype.h>
  48. #if HTS_WIN
  49. #else
  50. #ifndef HTS_DO_NOT_USE_UID
  51. /* setuid */
  52. #include <pwd.h>
  53. #ifdef HAVE_UNISTD_H
  54. #include <unistd.h>
  55. #endif
  56. #endif
  57. #endif
  58.  
  59. extern int exit_xh;          // sortir prΘmaturΘment
  60.  
  61. /* Resolver */
  62. extern int IPV6_resolver;
  63.  
  64.  
  65. // Add a command in the argc/argv
  66. #define cmdl_add(token,argc,argv,buff,ptr) \
  67.   argv[argc]=(buff+ptr); \
  68.   strcpybuff(argv[argc],token); \
  69.   ptr += (strlen(argv[argc])+2); \
  70.   argc++
  71.  
  72. // Insert a command in the argc/argv
  73. #define cmdl_ins(token,argc,argv,buff,ptr) \
  74.   { \
  75.   int i; \
  76.   for(i=argc;i>0;i--)\
  77.   argv[i]=argv[i-1];\
  78.   } \
  79.   argv[0]=(buff+ptr); \
  80.   strcpybuff(argv[0],token); \
  81.   ptr += (strlen(argv[0])+2); \
  82.   argc++
  83.  
  84. #define htsmain_free() do { if (url != NULL) { free(url); } } while(0)
  85.  
  86. #define ensureUrlCapacity(url, urlsize, size) do { \
  87.   if (urlsize < size || url == NULL) { \
  88.     urlsize = size; \
  89.     if (url == NULL) { \
  90.       url = (char*) malloct(urlsize); \
  91.       if (url != NULL) url[0]='\0'; \
  92.     } else { \
  93.       url = (char*) realloct(url, urlsize); \
  94.     } \
  95.     if (url == NULL) { \
  96.       HTS_PANIC_PRINTF("* memory exhausted"); \
  97.       htsmain_free(); \
  98.       return -1; \
  99.     } \
  100.   } \
  101. } while(0)
  102.  
  103. static void set_wrappers(void) {
  104. #if HTS_ANALYSTE
  105.   // custom wrappers
  106.   hts_htmlcheck_init         = (t_hts_htmlcheck_init)           htswrap_read("init");
  107.   hts_htmlcheck_uninit       = (t_hts_htmlcheck_uninit)         htswrap_read("free");
  108.   hts_htmlcheck_start        = (t_hts_htmlcheck_start)          htswrap_read("start");
  109.   hts_htmlcheck_end          = (t_hts_htmlcheck_end)            htswrap_read("end");
  110.   hts_htmlcheck_chopt        = (t_hts_htmlcheck_chopt)          htswrap_read("change-options");
  111.   hts_htmlcheck              = (t_hts_htmlcheck)                htswrap_read("check-html");
  112.   hts_htmlcheck_query        = (t_hts_htmlcheck_query)          htswrap_read("query");
  113.   hts_htmlcheck_query2       = (t_hts_htmlcheck_query2)         htswrap_read("query2");
  114.   hts_htmlcheck_query3       = (t_hts_htmlcheck_query3)         htswrap_read("query3");
  115.   hts_htmlcheck_loop         = (t_hts_htmlcheck_loop)           htswrap_read("loop");
  116.   hts_htmlcheck_check        = (t_hts_htmlcheck_check)          htswrap_read("check-link");
  117.   hts_htmlcheck_pause        = (t_hts_htmlcheck_pause)          htswrap_read("pause");
  118.   hts_htmlcheck_filesave     = (t_hts_htmlcheck_filesave)       htswrap_read("save-file");
  119.   hts_htmlcheck_linkdetected = (t_hts_htmlcheck_linkdetected)   htswrap_read("link-detected");
  120.   hts_htmlcheck_xfrstatus    = (t_hts_htmlcheck_xfrstatus)      htswrap_read("transfer-status");
  121.   hts_htmlcheck_savename     = (t_hts_htmlcheck_savename)       htswrap_read("save-name");
  122.   hts_htmlcheck_sendhead     = (t_hts_htmlcheck_sendhead)       htswrap_read("send-header");
  123.   hts_htmlcheck_receivehead  = (t_hts_htmlcheck_receivehead)    htswrap_read("receive-header");
  124. #endif
  125. }
  126.  
  127. // Main, rΘcupΦre les paramΦtres et appelle le robot
  128. #if HTS_ANALYSTE
  129. HTSEXT_API int hts_main(int argc, char **argv) {
  130. #else
  131. int main(int argc, char **argv) {
  132. #endif
  133.   char* x_argv[999];      // Patch pour argv et argc: en cas de rΘcupΘration de ligne de commande
  134.   char* x_argvblk=NULL;   // (reprise ou update)
  135.   int   x_ptr=0;          // offset
  136.   /*
  137.   char* x_argv2[999];     // Patch pour config
  138.   char* x_argvblk2=NULL;
  139.   */
  140.   //
  141.   int argv_url=-1;           // ==0 : utiliser cache et doit.log
  142.   char* argv_firsturl=NULL;  // utilisΘ pour nommage par dΘfaut
  143.   char* url = NULL;          // URLS sΘparΘes par un espace
  144.   int   url_sz = 65535;
  145.   //char url[65536];         // URLS sΘparΘes par un espace
  146.   // the parametres
  147.   httrackp httrack;
  148.   int httrack_logmode=3;   // ONE log file
  149.   int recuperer=0;       // rΘcupΘrer un plantage (n'arrive jamais, α supprimer)
  150. #if HTS_WIN
  151. #if HTS_ANALYSTE!=2
  152.   WORD   wVersionRequested; /* requested version WinSock API */ 
  153.   WSADATA wsadata;        /* Windows Sockets API data */
  154. #endif
  155. #else
  156. #ifndef HTS_DO_NOT_USE_UID
  157.   int switch_uid=-1,switch_gid=-1;      /* setuid/setgid */
  158. #endif
  159.   int switch_chroot=0;                  /* chroot ? */
  160. #endif
  161.   //
  162.   ensureUrlCapacity(url, url_sz, 65536);
  163.   //
  164.  
  165. #if HTS_ANALYSTE
  166.   // custom wrappers
  167.   set_wrappers();
  168. #endif
  169.  
  170.   // options par dΘfaut
  171.   memset(&httrack, 0, sizeof(httrackp));
  172.   httrack.wizard=2;   // wizard automatique
  173.   httrack.quiet=0;     // questions
  174.   //  
  175.   httrack.travel=0;   // mΩme adresse
  176.   httrack.depth=9999; // mirror total par dΘfaut
  177.   httrack.extdepth=0; // mais pas α l'extΘrieur
  178.   httrack.seeker=1;   // down 
  179.   httrack.urlmode=2;  // relatif par dΘfaut
  180.   httrack.debug=0;    // pas de dΘbug en plus
  181.   httrack.getmode=3;  // linear scan
  182.   httrack.maxsite=-1; // taille max site (aucune)
  183.   httrack.maxfile_nonhtml=-1; // taille max fichier non html
  184.   httrack.maxfile_html=-1;    // idem pour html
  185.   httrack.maxsoc=4;     // nbre socket max
  186.   httrack.fragment=-1;  // pas de fragmentation
  187.   httrack.nearlink=0;   // ne pas prendre les liens non-html "adjacents"
  188.   httrack.makeindex=1;  // faire un index
  189.   httrack.kindex=0;     // index 'keyword'
  190.   httrack.delete_old=1; // effacer anciens fichiers
  191.   httrack.makestat=0;  // pas de fichier de stats
  192.   httrack.maketrack=0; // ni de tracking
  193.   httrack.timeout=120; // timeout par dΘfaut (2 minutes)
  194.   httrack.cache=1;     // cache prioritaire
  195.   httrack.shell=0;     // pas de shell par defaut
  196.   httrack.proxy.active=0;    // pas de proxy
  197.   strcpybuff(httrack.proxy.bindhost, "");  // bind default host
  198.   httrack.user_agent_send=1; // envoyer un user-agent
  199.   strcpybuff(httrack.user_agent,"Mozilla/4.5 (compatible; HTTrack 3.0x; Windows 98)");
  200.   httrack.savename_83=0;     // noms longs par dΘfaut
  201.   httrack.savename_type=0;   // avec structure originale
  202.   httrack.mimehtml=0;        // pas MIME-html
  203.   httrack.parsejava=1;       // parser classes
  204.   httrack.hostcontrol=0;     // PAS de control host pour timeout et traffic jammer
  205.   httrack.retry=2;           // 2 retry par dΘfaut
  206.   httrack.errpage=1;         // copier ou gΘnΘrer une page d'erreur en cas d'erreur (404 etc.)
  207.   httrack.check_type=1;      // vΘrifier type si inconnu (cgi,asp..) SAUF / considΘrΘ comme html
  208.   httrack.all_in_cache=0;    // ne pas tout stocker en cache
  209.   httrack.robots=2;          // traiter les robots.txt
  210.   httrack.external=0;        // liens externes normaux
  211.   httrack.passprivacy=0;     // mots de passe dans les fichiers
  212.   httrack.includequery=1;    // include query-string par dΘfaut
  213.   httrack.mirror_first_page=0;  // pas mode mirror links
  214.   httrack.accept_cookie=1;   // gΘrer les cookies
  215.   httrack.cookie=NULL;
  216.   httrack.http10=0;          // laisser http/1.1
  217.   httrack.nokeepalive = 0;   // pas keep-alive
  218.   httrack.nocompression=0;   // pas de compression
  219.   httrack.tolerant=0;        // ne pas accepter content-length incorrect
  220.   httrack.parseall=1;        // tout parser (tags inconnus, par exemple)
  221.   httrack.norecatch=0;       // ne pas reprendre les fichiers effacΘs par l'utilisateur
  222.   httrack.verbosedisplay=0;  // pas d'animation texte
  223.   httrack.sizehack=0;        // size hack
  224.   httrack.urlhack=1;         // url hack (normalizer)
  225.   strcpybuff(httrack.footer,HTS_DEFAULT_FOOTER);
  226.   httrack.ftp_proxy=1;       // proxy http pour ftp
  227.   strcpybuff(httrack.filelist,"");
  228.   strcpybuff(httrack.lang_iso,"en, *");
  229.   strcpybuff(httrack.mimedefs,"\n"); // aucun filtre mime (\n IMPORTANT)
  230.   //
  231.   httrack.log=stdout;
  232.   httrack.errlog=stderr;
  233.   httrack.flush=1;           // flush sur les fichiers log
  234.   //httrack.aff_progress=0;
  235.   httrack.keyboard=0;
  236.   //
  237.   strcpybuff(httrack.path_html,"");
  238.   strcpybuff(httrack.path_log,"");
  239.   strcpybuff(httrack.path_bin,"");
  240.   //
  241.   httrack.maxlink=100000;    // 100,000 liens max par dΘfaut (400Kb)
  242.   httrack.maxfilter=200;     // 200 filtres max par dΘfaut
  243.   httrack.maxcache=1048576*32;  // a peu prΦs 32Mo en cache max -- OPTION NON PARAMETRABLE POUR L'INSTANT --
  244.   //httrack.maxcache_anticipate=256;  // maximum de liens α anticiper
  245.   httrack.maxtime=-1;        // temps max en secondes
  246.   httrack.maxrate=-1;        // pas de taux maxi
  247.   httrack.maxconn=10;        // nombre connexions/s
  248.   httrack.waittime=-1;       // wait until.. hh*3600+mm*60+ss
  249.   //
  250.   httrack.exec=argv[0];
  251.   httrack.is_update=0;      // not an update (yet)
  252.   httrack.dir_topindex=0;   // do not built top index (yet)
  253.   //
  254.   httrack.state.stop=0;     // stopper
  255.   httrack.state.exit_xh=0;  // abort
  256.   //
  257.   _DEBUG_HEAD=0;            // pas de debuggage en tΩtes
  258.  
  259.   
  260. #if HTS_WIN
  261. #if HTS_ANALYSTE!=2
  262.   {
  263.     int stat;
  264.     wVersionRequested = 0x0101;
  265.     stat = WSAStartup( wVersionRequested, &wsadata );
  266.     if (stat != 0) {
  267.       HTS_PANIC_PRINTF("Winsock not found!\n");
  268.       htsmain_free();
  269.       return -1;
  270.     } else if (LOBYTE(wsadata.wVersion) != 1  && HIBYTE(wsadata.wVersion) != 1) {
  271.       HTS_PANIC_PRINTF("WINSOCK.DLL does not support version 1.1\n");
  272.       WSACleanup();
  273.       htsmain_free();
  274.       return -1;
  275.     }
  276.   }
  277. #endif
  278. #endif
  279.  
  280.   /* Init root dir */
  281.   hts_rootdir(argv[0]);
  282.  
  283. #if HTS_WIN
  284. #else
  285.   /* Terminal is a tty, may ask questions and display funny information */
  286.   if (isatty(1)) {
  287.     httrack.quiet=0;
  288.     httrack.verbosedisplay=1;
  289.   }
  290.   /* Not a tty, no stdin input or funny output! */
  291.   else {
  292.     httrack.quiet=1;
  293.     httrack.verbosedisplay=0;
  294.   }
  295. #endif
  296.  
  297.   /* First test: if -#R then only launch ftp */
  298.   if (argc > 2) {
  299.     if (strcmp(argv[1],"-#R")==0) {
  300.       if (argc==6) {
  301.         lien_back r;
  302.         char* path;
  303.         FILE* fp;
  304.         strcpybuff(r.url_adr,argv[2]);
  305.         strcpybuff(r.url_fil,argv[3]);
  306.         strcpybuff(r.url_sav,argv[4]);
  307.         path=argv[5];
  308.         r.status=1000;
  309.         run_launch_ftp(&r);
  310.         fp=fopen(fconv(path),"wb");
  311.         if (fp) {
  312.           fprintf(fp,"%d %s",r.r.statuscode,r.r.msg);
  313.           fclose(fp); fp=NULL;
  314.           rename(fconv(path),fconcat(path,".ok"));
  315.         } else remove(fconv(path));
  316.       } else {
  317.         printf("htsftp error, wrong parameter number (%d)\n",argc);
  318.       }
  319.       exit(0);   // pas _exit()
  320.     }
  321.   }
  322.  
  323.   // ok, non ftp, continuer
  324.  
  325.  
  326.   // Binary program path?
  327. #ifndef HTS_HTTRACKDIR
  328.   {
  329.     char* path=fslash(argv[0]);
  330.     char* a;
  331.     if ((a=strrchr(path,'/'))) {
  332.       httrack.path_bin[0]='\0';
  333.       strncatbuff(httrack.path_bin,argv[0],(int) a - (int) path);
  334.     }
  335.   }
  336. #else
  337.   strcpybuff(httrack.path_bin, HTS_HTTRACKDIR);
  338. #endif
  339.  
  340.  
  341.   /* filter CR, LF, TAB.. */
  342.   {
  343.     int na;
  344.     for(na=1;na<argc;na++) {
  345.       char* a;
  346.       while( (a=strchr(argv[na],'\x0d')) ) *a=' ';
  347.       while( (a=strchr(argv[na],'\x0a')) ) *a=' ';
  348.       while( (a=strchr(argv[na],9)) )      *a=' ';
  349.       /* equivalent to "empty parameter" */
  350.       if ((strcmp(argv[na],HTS_NOPARAM)==0) || (strcmp(argv[na],HTS_NOPARAM2)==0))        // (none)
  351.         strcpybuff(argv[na],"\"\"");
  352.       if (strncmp(argv[na],"-&",2)==0)
  353.         argv[na][1]='%';
  354.     }
  355.   }
  356.  
  357.  
  358.  
  359.   /* create x_argvblk buffer for transformed command line */
  360.   {
  361.     int current_size=0;
  362.     int size;
  363.     int na;
  364.     for(na=0;na<argc;na++)
  365.       current_size += (strlen(argv[na]) + 1);
  366.     if ((size=fsize("config"))>0)
  367.       current_size += size;
  368.     x_argvblk=(char*) malloct(current_size+32768);
  369.     if (x_argvblk == NULL) {
  370.       HTS_PANIC_PRINTF("Error, not enough memory");
  371.       htsmain_free();
  372.       return -1;
  373.     }
  374.     x_argvblk[0]='\0';
  375.     x_ptr=0;
  376.   }
  377.  
  378.   /* Create new argc/argv, replace alias, count URLs, treat -h, -q, -i */
  379.   {
  380.     char _tmp_argv[2][HTS_CDLMAXSIZE];
  381.     char* tmp_argv[2];
  382.     char tmp_error[HTS_CDLMAXSIZE];
  383.     int tmp_argc;
  384.     int x_argc=0;
  385.     int na;
  386.     tmp_argv[0]=_tmp_argv[0];
  387.     tmp_argv[1]=_tmp_argv[1];
  388.     //
  389.     argv_url=0;       /* pour comptage */
  390.     //
  391.     cmdl_add(argv[0],x_argc,x_argv,x_argvblk,x_ptr);
  392.     na=1;             /* commencer aprΦs nom_prg */
  393.     while(na<argc) {
  394.       int result=1;
  395.       tmp_argv[0][0]=tmp_argv[1][0]='\0';
  396.  
  397.       /* VΘrifier argv[] non vide */
  398.       if (strnotempty(argv[na])) {
  399.         
  400.         /* VΘrifier Commande (alias) */
  401.         result=optalias_check(argc,(const char * const *)argv,na,
  402.           &tmp_argc,(char**)tmp_argv,tmp_error);
  403.         if (!result) {
  404.           HTS_PANIC_PRINTF(tmp_error);
  405.           htsmain_free();
  406.           return -1;
  407.         }
  408.         
  409.         /* Copier */
  410.         cmdl_add(tmp_argv[0],x_argc,x_argv,x_argvblk,x_ptr);
  411.         if (tmp_argc > 1) {
  412.           cmdl_add(tmp_argv[1],x_argc,x_argv,x_argvblk,x_ptr);
  413.         }
  414.         
  415.         /* Compter URLs et dΘtecter -i,-q.. */
  416.         if (tmp_argc == 1) {           /* pas -P & co */
  417.           if (!cmdl_opt(tmp_argv[0])) {   /* pas -c0 & co */
  418.             if (argv_url<0) argv_url=0;   // -1==force -> 1=one url already detected, wipe all previous options
  419.             //if (argv_url>=0) {
  420.             argv_url++;
  421.             if (!argv_firsturl)
  422.               argv_firsturl=x_argv[x_argc-1];
  423.             //}
  424.           } else {
  425.             if (strcmp(tmp_argv[0],"-h")==0) {
  426.               help(argv[0],!httrack.quiet);
  427.               htsmain_free();
  428.               return 0;
  429.             } else {
  430.               if (strncmp(tmp_argv[0],"--",2)) {   /* pas */
  431.                 if ((strchr(tmp_argv[0],'q')!=NULL))
  432.                   httrack.quiet=1;    // ne pas poser de questions! (nohup par exemple)
  433.                 if ((strchr(tmp_argv[0],'i')!=NULL)) {  // doit.log!
  434.                   argv_url=-1;        /* forcer */
  435.                   httrack.quiet=1;
  436.                 }
  437.               } else if (strcmp(tmp_argv[0] + 2,"quiet") == 0) {
  438.                 httrack.quiet=1;    // ne pas poser de questions! (nohup par exemple)
  439.               } else if (strcmp(tmp_argv[0] + 2,"continue") == 0) {
  440.                 argv_url=-1;        /* forcer */
  441.                 httrack.quiet=1;
  442.               }
  443.             }
  444.           }
  445.         } else if (tmp_argc == 2) {
  446.           if ((strcmp(tmp_argv[0],"-%L")==0)) {  // liste d'URLs
  447.             if (argv_url<0) argv_url=0;   // -1==force -> 1=one url already detected, wipe all previous options
  448.             //if (argv_url>=0)
  449.             argv_url++;        /* forcer */
  450.           }
  451.         }
  452.       }
  453.  
  454.       na+=result;
  455.     }
  456.     if (argv_url<0)
  457.       argv_url=0;
  458.  
  459.     /* Nouveaux argc et argv */
  460.     argv=x_argv;
  461.     argc=x_argc;
  462.   }
  463.  
  464.  
  465.  
  466.  
  467.   // Ici on ajoute les arguments de config
  468. /*
  469.   if (fexist("config")) {    // configuration        
  470.     x_argvblk2=(char*) calloct(32768,1);
  471.  
  472.     if (x_argvblk2!=NULL) {
  473.       FILE* fp;
  474.       int x_argc2;
  475.           
  476.       //strcpybuff(x_argvblk2,"httrack ");
  477.       fp=fopen("config","rb");
  478.       if (fp) {
  479.         linput(fp,x_argvblk2+strlen(x_argvblk2),32000);
  480.         fclose(fp); fp=NULL;
  481.     
  482.         // calculer arguments selon derniers arguments
  483.         x_argv2[0]=argv[0];
  484.         x_argc2=1;
  485.         {
  486.           char* p=x_argvblk2;
  487.           do {
  488.             x_argv2[x_argc2++]=p;
  489.             p=strchr(p,' ');
  490.             if (p) {
  491.               *p=0;    // octet nul (tableau)
  492.               p++;
  493.             }            
  494.           } while(p!=NULL);
  495.         }
  496.         // recopier arguments actuels (pointeurs uniquement)
  497.         {
  498.          int na;
  499.           for(na=1;na<argc;na++) {
  500.             x_argv2[x_argc2++]=argv[na];
  501.           }
  502.         }
  503.         argc=x_argc2;      // nouvel argc
  504.         argv=x_argv2;      // nouvel argv
  505.       }
  506.     }
  507.   }
  508. */
  509.  
  510.  
  511.   // Option O and includerc
  512.   { 
  513.     int loops=0;
  514.     while (loops<2) {
  515.       char* com;
  516.       int na;
  517.       
  518.       for(na=1;na<argc;na++) {
  519.         
  520.         if (argv[na][0]=='"') {
  521.           char tempo[HTS_CDLMAXSIZE];
  522.           strcpybuff(tempo,argv[na]+1);
  523.           if (tempo[strlen(tempo)-1]!='"') {
  524.             char s[HTS_CDLMAXSIZE];
  525.             sprintf(s,"Missing quote in %s",argv[na]);
  526.             HTS_PANIC_PRINTF(s);
  527.             htsmain_free();
  528.             return -1;
  529.           }
  530.           tempo[strlen(tempo)-1]='\0';
  531.           strcpybuff(argv[na],tempo);
  532.         }
  533.         
  534.         if (cmdl_opt(argv[na])) { // option
  535.           com=argv[na]+1;
  536.           
  537.           while(*com) {
  538.             switch(*com) {
  539.             case 'O':    // output path
  540.               if ((na+1>=argc) || (argv[na+1][0]=='-')) {
  541.                 HTS_PANIC_PRINTF("Option O needs to be followed by a blank space, and a path (or path,path)");
  542.                 printf("Example: -O /binary/\n");
  543.                 printf("Example: -O /binary/,/log/\n");
  544.                 htsmain_free();
  545.                 return -1;
  546.               } else {
  547.                 char* a;
  548.                 na++;
  549.                 strcpybuff(httrack.path_html,"");
  550.                 strcpybuff(httrack.path_log,"");
  551.                 a=strstr(argv[na],"\",\"");  // rechercher en premier, au cas ou -O "c:\pipo,test","c:\test"
  552.                 if (!a)
  553.                   a=strchr(argv[na],',');  // 2 path
  554.                 else
  555.                   a++;  // position ,
  556.                 if (a) {
  557.                   strncatbuff(httrack.path_html,argv[na],(int) (a-argv[na]));
  558.                   strcatbuff(httrack.path_log,a+1);
  559.                 } else {
  560.                   strcpybuff(httrack.path_log,argv[na]);
  561.                   strcpybuff(httrack.path_html,argv[na]);
  562.                 }
  563.                 // Eliminer les cas comme -O "C:\mirror\"
  564.                 if (httrack.path_log[0]=='"') {  // Guillemets
  565.                   char tmp[256];
  566.                   strcpybuff(tmp,httrack.path_log+1);
  567.                   if (tmp[strlen(tmp)-1]=='"')
  568.                     tmp[strlen(tmp)-1]='\0';
  569.                   strcpybuff(httrack.path_log,tmp);
  570.                 }
  571.                 if (httrack.path_html[0]=='"') {
  572.                   char tmp[256];
  573.                   strcpybuff(tmp,httrack.path_html+1);
  574.                   if (tmp[strlen(tmp)-1]=='"')
  575.                     tmp[strlen(tmp)-1]='\0';
  576.                   strcpybuff(httrack.path_html,tmp);
  577.                 }
  578.                 check_path(httrack.path_log,argv_firsturl);
  579.                 if (check_path(httrack.path_html,argv_firsturl)) {
  580.                   httrack.dir_topindex=1;     // rebuilt top index
  581.                 }
  582.                 
  583.                 //printf("-->%s\n%s\n",httrack.path_html,httrack.path_log);
  584.                 
  585.               }
  586.               break;
  587.             }  // switch
  588.             com++;    
  589.           }  // while
  590.           
  591.         }  // arg
  592.         
  593.       }  // for
  594.      
  595.          /* if doit.log exists, or if new URL(s) defined, 
  596.       then DO NOT load standard config files */
  597.       /* (config files are added in doit.log) */
  598. #if DEBUG_STEPS
  599.       printf("Loading httrackrc/doit.log\n");
  600. #endif
  601.       /* recreate a doit.log (no old doit.log or new URLs (and parameters)) */
  602.       if ((strnotempty(httrack.path_log)) || (strnotempty(httrack.path_html)))
  603.         loops++;      // do not loop once again and do not include rc file (O option exists)
  604.       else {
  605.         if ( (!fexist(fconcat(httrack.path_log,"hts-cache/doit.log"))) || (argv_url>0) ) {
  606.           if (!optinclude_file(fconcat(httrack.path_log,HTS_HTTRACKRC),&argc,argv,x_argvblk,&x_ptr))
  607.             if (!optinclude_file(HTS_HTTRACKRC,&argc,argv,x_argvblk,&x_ptr)) {
  608.               if (!optinclude_file(fconcat(hts_gethome(),"/"HTS_HTTRACKRC),&argc,argv,x_argvblk,&x_ptr)) {
  609. #ifdef HTS_HTTRACKCNF
  610.                 optinclude_file(HTS_HTTRACKCNF,&argc,argv,x_argvblk,&x_ptr);
  611. #endif
  612.               }
  613.             }
  614.         } else
  615.           loops++;      // do not loop once again
  616.       }
  617.  
  618.       loops++;
  619.    } // while
  620.  
  621.   }  // traiter -O
  622.  
  623.   /* load doit.log and insert in current command line */
  624.   if ( fexist(fconcat(httrack.path_log,"hts-cache/doit.log")) && (argv_url<=0) ) {
  625.     FILE* fp=fopen(fconcat(httrack.path_log,"hts-cache/doit.log"),"rb");
  626.     if (fp) {
  627.       int insert_after=1;     /* insΘrer aprΦs nom au dΘbut */
  628.       //
  629.       char buff[8192];
  630.       char *p,*lastp;
  631.       linput(fp,buff,8000);
  632.       fclose(fp); fp=NULL;
  633.       p=buff;
  634.       do {
  635.         int insert_after_argc;
  636.         // read next
  637.         lastp=p;
  638.         if (p) {
  639.           p=next_token(p,1);
  640.           if (p) {
  641.             *p=0;    // null
  642.             p++;
  643.           }
  644.         }
  645.  
  646.         /* Insert parameters BUT so that they can be in the same order */
  647.         if (lastp) {
  648.           if (strnotempty(lastp)) {
  649.             //char* argv0;
  650.             //int len;
  651.             insert_after_argc=argc-insert_after;
  652.             //argv0 = (argv+insert_after)[0];
  653.             cmdl_ins(lastp,insert_after_argc,(argv+insert_after),x_argvblk,x_ptr);
  654.             /*
  655.             DONE IN 'next_token'
  656.             len = strlen(argv0);
  657.             if (len >= 2 && argv0[0]=='\"' && argv0[len-1]=='\"') {   // "foo"
  658.               char tempo[1024];
  659.               tempo[0] = '\0';
  660.               strncatbuff(tempo, argv0+1, len-2);
  661.               strcpybuff(argv0, tempo);
  662.             }
  663.             */
  664.             argc=insert_after_argc+insert_after;
  665.             insert_after++;
  666.           }
  667.         }
  668.       } while(lastp!=NULL);
  669.       //fclose(fp);
  670.     }
  671.   }
  672.  
  673.  
  674.   // Existence d'un cache - pas de new mais un old.. renommer
  675. #if DEBUG_STEPS
  676.   printf("Checking cache\n");
  677. #endif
  678.   if ( (!fexist(fconcat(httrack.path_log,"hts-cache/new.dat"))) || (!fexist(fconcat(httrack.path_log,"hts-cache/new.ndx"))) ) {
  679.     if ( (fexist(fconcat(httrack.path_log,"hts-cache/old.dat"))) && (fexist(fconcat(httrack.path_log,"hts-cache/old.ndx"))) ) {
  680.       remove(fconcat(httrack.path_log,"hts-cache/new.dat"));
  681.       remove(fconcat(httrack.path_log,"hts-cache/new.ndx"));
  682.       //remove(fconcat(httrack.path_log,"hts-cache/new.lst"));
  683.       rename(fconcat(httrack.path_log,"hts-cache/old.dat"),fconcat(httrack.path_log,"hts-cache/new.dat"));
  684.       rename(fconcat(httrack.path_log,"hts-cache/old.ndx"),fconcat(httrack.path_log,"hts-cache/new.ndx"));
  685.       //rename(fconcat(httrack.path_log,"hts-cache/old.lst"),fconcat(httrack.path_log,"hts-cache/new.lst"));
  686.     }
  687.   }
  688.  
  689.   /* Interrupted mirror detected */
  690.   if (!httrack.quiet) {
  691.     if (fexist(fconcat(httrack.path_log,"hts-in_progress.lock"))) {
  692.       /* Old cache */
  693.       if ( (fexist(fconcat(httrack.path_log,"hts-cache/old.dat"))) && (fexist(fconcat(httrack.path_log,"hts-cache/old.ndx"))) ) {
  694.         if (httrack.log != NULL) {
  695.           fprintf(httrack.log,"Warning!\n");
  696.           fprintf(httrack.log,"An aborted mirror has been detected!\nThe current temporary cache is required for any update operation and only contains data downloaded during the last aborted session.\nThe former cache might contain more complete information; if you do not want to lose that information, you have to restore it and delete the current cache.\nThis can easily be done here by erasing the hts-cache/new.* files\n");
  697.           fprintf(httrack.log,"Please restart HTTrack with --continue (-iC1) option to override this message!\n");
  698.         }
  699.         exit(0);
  700.       }
  701.     }
  702.   }
  703.     
  704.   // remplacer "macros" comme --spider
  705.   // permet de lancer httrack sans a avoir α se rappeler de syntaxes comme p0C0I0Qc32 ..
  706. #if DEBUG_STEPS
  707.   printf("Checking last macros\n");
  708. #endif
  709.   {
  710.     int i;
  711.     for(i=0;i<argc;i++) {
  712. #if DEBUG_STEPS
  713.       printf("Checking #%d:\n",argv[i]);
  714.       printf("%s\n",argv[i]);
  715. #endif
  716.       if (argv[i][0]=='-') {
  717.         if (argv[i][1]=='-') {  // --xxx
  718.           if ((strfield2(argv[i]+2,"clean")) || (strfield2(argv[i]+2,"tide"))) {  // nettoyer
  719.             strcpybuff(argv[i]+1,"");
  720.             if (fexist(fconcat(httrack.path_log,"hts-log.txt")))
  721.               remove(fconcat(httrack.path_log,"hts-log.txt"));
  722.             if (fexist(fconcat(httrack.path_log,"hts-err.txt")))
  723.               remove(fconcat(httrack.path_log,"hts-err.txt"));
  724.             if (fexist(fconcat(httrack.path_html,"index.html")))
  725.               remove(fconcat(httrack.path_html,"index.html"));
  726.             if (fexist(fconcat(httrack.path_log,"hts-cache/new.dat")))
  727.               remove(fconcat(httrack.path_log,"hts-cache/new.dat"));
  728.             if (fexist(fconcat(httrack.path_log,"hts-cache/new.ndx")))
  729.               remove(fconcat(httrack.path_log,"hts-cache/new.ndx"));
  730.             if (fexist(fconcat(httrack.path_log,"hts-cache/old.dat")))
  731.               remove(fconcat(httrack.path_log,"hts-cache/old.dat"));
  732.             if (fexist(fconcat(httrack.path_log,"hts-cache/old.ndx")))
  733.               remove(fconcat(httrack.path_log,"hts-cache/old.ndx"));
  734.             if (fexist(fconcat(httrack.path_log,"hts-cache/new.lst")))
  735.               remove(fconcat(httrack.path_log,"hts-cache/new.lst"));
  736.             if (fexist(fconcat(httrack.path_log,"hts-cache/old.lst")))
  737.               remove(fconcat(httrack.path_log,"hts-cache/old.lst"));
  738.             if (fexist(fconcat(httrack.path_log,"hts-cache/new.txt")))
  739.               remove(fconcat(httrack.path_log,"hts-cache/new.txt"));
  740.             if (fexist(fconcat(httrack.path_log,"hts-cache/old.txt")))
  741.               remove(fconcat(httrack.path_log,"hts-cache/old.txt"));
  742.             if (fexist(fconcat(httrack.path_log,"hts-cache/doit.log")))
  743.               remove(fconcat(httrack.path_log,"hts-cache/doit.log"));
  744.             if (fexist(fconcat(httrack.path_log,"hts-in_progress.lock")))
  745.               remove(fconcat(httrack.path_log,"hts-in_progress.lock"));
  746.             rmdir(fconcat(httrack.path_log,"hts-cache"));
  747.             //
  748.           } else if (strfield2(argv[i]+2,"catchurl")) {      // capture d'URL via proxy temporaire!
  749.             argv_url=1;     // forcer a passer les parametres
  750.             strcpybuff(argv[i]+1,"#P");
  751.             //
  752.           } else if (strfield2(argv[i]+2,"updatehttrack")) {
  753. #ifdef _WIN32
  754.             char s[HTS_CDLMAXSIZE];
  755.             sprintf(s,"%s not available in this version",argv[i]);
  756.             HTS_PANIC_PRINTF(s);
  757.             htsmain_free();
  758.             return -1;
  759. #else
  760. #if 0
  761.             char _args[8][256];
  762.             char *args[8];
  763.             
  764.             printf("Cheking for updates...\n");
  765.             strcpybuff(_args[0],argv[0]);
  766.             strcpybuff(_args[1],"--get");
  767.             sprintf(_args[2],HTS_UPDATE_WEBSITE,HTS_PLATFORM,"");
  768.             strcpybuff(_args[3],"--quickinfo");
  769.             args[0]=_args[0];
  770.             args[1]=_args[1];
  771.             args[2]=_args[2];
  772.             args[3]=_args[3];
  773.             args[4]=NULL;
  774.             if (execvp(args[0],args)==-1) {
  775.             }
  776. #endif
  777. #endif
  778.           }
  779.           //
  780.           else {
  781.             char s[HTS_CDLMAXSIZE];
  782.             sprintf(s,"%s not recognized",argv[i]);
  783.             HTS_PANIC_PRINTF(s);
  784.             htsmain_free();
  785.             return -1;
  786.           }
  787.  
  788.         } 
  789.       }
  790.     }
  791.   }
  792.  
  793.   // Compter urls/jokers
  794.   /*
  795.   if (argv_url<=0) { 
  796.     int na;
  797.     argv_url=0;
  798.     for(na=1;na<argc;na++) {
  799.       if ( (strcmp(argv[na],"-P")==0) || (strcmp(argv[na],"-N")==0) || (strcmp(argv[na],"-F")==0) || (strcmp(argv[na],"-O")==0) || (strcmp(argv[na],"-V")==0) ) {
  800.         na++;    // sauter nom de proxy
  801.       } else if (!cmdl_opt(argv[na])) { 
  802.         argv_url++;   // un de plus       
  803.       } else if (strcmp(argv[na],"-h")==0) {
  804.         help(argv[0],!httrack.quiet);
  805.         htsmain_free();
  806.         return 0;
  807.       } else {
  808.         if ((strchr(argv[na],'q')!=NULL))
  809.           httrack.quiet=1;    // ne pas poser de questions! (nohup par exemple)
  810.         if ((strchr(argv[na],'i')!=NULL)) {  // doit.log!
  811.           argv_url=0;
  812.           na=argc;
  813.         }
  814.       }
  815.     }
  816.   }  
  817.   */
  818.  
  819.   // Ici on ajoute les arguments qui ont ΘtΘ appelΘs avant au cas o∙ on rΘcupΦre une session
  820.   // Exemple: httrack www.truc.fr -L0 puis ^C puis httrack sans URL : ajouter URL prΘcΘdente
  821.   /*
  822.   if (argv_url==0) {
  823.     //if ((fexist(fconcat(httrack.path_log,"hts-cache/new.dat"))) && (fexist(fconcat(httrack.path_log,"hts-cache/new.ndx")))) {  // il existe dΘja un cache prΘcΘdent.. renommer
  824.     if (fexist(fconcat(httrack.path_log,"hts-cache/doit.log"))) {    // un cache est prΘsent
  825.       
  826.       x_argvblk=(char*) calloct(32768,1);
  827.       
  828.       if (x_argvblk!=NULL) {
  829.         FILE* fp;
  830.         int x_argc;
  831.         
  832.         //strcpybuff(x_argvblk,"httrack ");
  833.         fp=fopen(fconcat(httrack.path_log,"hts-cache/doit.log"),"rb");
  834.         if (fp) {
  835.           linput(fp,x_argvblk+strlen(x_argvblk),8192);
  836.           fclose(fp); fp=NULL;
  837.         }
  838.         
  839.         // calculer arguments selon derniers arguments
  840.         x_argv[0]=argv[0];
  841.         x_argc=1;
  842.         {
  843.           char* p=x_argvblk;
  844.           do {
  845.             x_argv[x_argc++]=p;
  846.             //p=strstr(p," ");
  847.             // exemple de chaine: "echo \"test\"" c:\a "\$0"
  848.             p=next_token(p,1);    // prochain token
  849.             if (p) {
  850.               *p=0;    // octet nul (tableau)
  851.               p++;
  852.             }            
  853.           } while(p!=NULL);
  854.         }
  855.         // recopier arguments actuels (pointeurs uniquement)
  856.         {
  857.           int na;
  858.           for(na=1;na<argc;na++) {
  859.             if (strcmp(argv[na],"-O") != 0)    // SAUF le path!
  860.               x_argv[x_argc++]=argv[na];
  861.             else
  862.               na++;
  863.           }
  864.         }
  865.         argc=x_argc;      // nouvel argc
  866.         argv=x_argv;      // nouvel argv
  867.       }
  868.       
  869.       
  870.     }
  871.     //}
  872.   }
  873.   */
  874.   
  875.   // VΘrifier quiet
  876.   /*
  877.   { 
  878.     int na;    
  879.     for(na=1;na<argc;na++) {
  880.       if (!cmdl_opt(argv[na])) { 
  881.         if ((strcmp(argv[na],"-P")==0) || (strcmp(argv[na],"-N")==0) || (strcmp(argv[na],"-F")==0) || (strcmp(argv[na],"-O")==0) || (strcmp(argv[na],"-V")==0))
  882.           na++;    // sauter nom de proxy
  883.       } else {
  884.         if ((strchr(argv[na],'q')!=NULL) || (strchr(argv[na],'i')!=NULL))
  885.           httrack.quiet=1;    // ne pas poser de questions! (nohup par exemple)
  886.       }
  887.     }
  888.   }
  889.   */
  890.  
  891.   // Pas d'URL
  892. #if DEBUG_STEPS
  893.   printf("Checking URLs\n");
  894. #endif
  895.   if (argv_url==0) {
  896.     // PrΘsence d'un cache, que faire?..
  897.     if ((fexist(fconcat(httrack.path_log,"hts-cache/new.dat"))) && (fexist(fconcat(httrack.path_log,"hts-cache/new.ndx")))) {  // il existe dΘja un cache prΘcΘdent.. renommer
  898.       if (fexist(fconcat(httrack.path_log,"hts-cache/doit.log"))) {    // un cache est prΘsent
  899.         if (x_argvblk!=NULL) {
  900.           int m;        
  901.           // Θtablir mode - mode cache: 1 (cache valide) 2 (cache α vΘrifier)
  902.           if (fexist(fconcat(httrack.path_log,"hts-in_progress.lock"))) {    // cache prioritaire
  903.             m=1;
  904.             recuperer=1;
  905.           } else {
  906.             m=2;
  907.           }
  908.           httrack.cache=m;
  909.           
  910.           if (httrack.quiet==0) {  // sinon on continue automatiquement
  911.             HT_REQUEST_START;
  912.             HT_PRINT("A cache (hts-cache/) has been found in the directory ");
  913.             HT_PRINT(httrack.path_log);
  914.             HT_PRINT(LF);
  915.             if (m==1) {
  916.               HT_PRINT("That means that a transfer has been aborted"LF);
  917.               HT_PRINT("OK to Continue ");
  918.             } else {
  919.               HT_PRINT("That means you can update faster the remote site(s)"LF);
  920.               HT_PRINT("OK to Update ");
  921.             }
  922.             HT_PRINT("httrack "); HT_PRINT(x_argvblk); HT_PRINT("?"LF);
  923.             HT_REQUEST_END;
  924.             if (!ask_continue()) { 
  925.               htsmain_free();
  926.               return 0;
  927.             }
  928.           }
  929.           
  930.         } else {
  931.           HTS_PANIC_PRINTF("Error, not enough memory");
  932.           htsmain_free();
  933.           return -1;
  934.         }
  935.       } else { // log existe pas
  936.         HTS_PANIC_PRINTF("A cache has been found, but no command line");
  937.         printf("Please launch httrack with proper parameters to reuse the cache\n");
  938.         htsmain_free();
  939.         return -1;
  940.       }
  941.       
  942.     } else {    // aucune URL dΘfinie et pas de cache
  943.       if (argc > 1 && strcmp(argv[0], "-#h") == 0) {
  944.         printf("HTTrack version "HTTRACK_VERSION"%s\n", WHAT_is_available);
  945.         exit(0);
  946.       }
  947. #if HTS_ANALYSTE!=2
  948.       if (httrack.quiet) {
  949. #endif
  950.         help(argv[0],!httrack.quiet);
  951.         htsmain_free();
  952.         return -1;
  953. #if HTS_ANALYSTE!=2
  954.       } else {
  955.         help_wizard(&httrack);
  956.         htsmain_free();
  957.         return -1;
  958.       }
  959. #endif
  960.       htsmain_free();
  961.       return 0;
  962.     }
  963.   } else {   // plus de 2 paramΦtres
  964.     // un fichier log existe?
  965.     if (fexist(fconcat(httrack.path_log,"hts-in_progress.lock"))) {  // fichier lock?
  966.       //char s[32];
  967.       
  968.       httrack.cache=1;    // cache prioritaire
  969.       if (httrack.quiet==0) {
  970.         if ((fexist(fconcat(httrack.path_log,"hts-cache/new.dat"))) && (fexist(fconcat(httrack.path_log,"hts-cache/new.ndx")))) {  // il existe dΘja un cache prΘcΘdent.. renommer
  971.           HT_REQUEST_START;
  972.           HT_PRINT("There is a lock-file in the directory ");
  973.           HT_PRINT(httrack.path_log);
  974.           HT_PRINT(LF"That means that a mirror has not been terminated"LF);
  975.           HT_PRINT("Be sure you call httrack with proper parameters"LF);
  976.           HT_PRINT("(The cache allows you to restart faster the transfer)"LF);
  977.           HT_REQUEST_END;
  978.           if (!ask_continue()) {
  979.             htsmain_free();
  980.             return 0;
  981.           }
  982.         }
  983.       }
  984.     } else if (fexist(fconcat(httrack.path_html,"index.html"))) {
  985.       //char s[32];
  986.       httrack.cache=2;  // cache vient aprΦs test de validitΘ
  987.       if (httrack.quiet==0) {
  988.         if ((fexist(fconcat(httrack.path_log,"hts-cache/new.dat"))) && (fexist(fconcat(httrack.path_log,"hts-cache/new.ndx")))) {  // il existe dΘja un cache prΘcΘdent.. renommer
  989.           HT_REQUEST_START;
  990.           HT_PRINT("There is an index.html and a hts-cache folder in the directory ");
  991.           HT_PRINT(httrack.path_log);
  992.           HT_PRINT(LF"A site may have been mirrored here, that could mean that you want to update it"LF);
  993.           HT_PRINT("Be sure parameters are ok"LF);
  994.           HT_REQUEST_END;
  995.           if (!ask_continue()) {
  996.             htsmain_free();
  997.             return 0;
  998.           }
  999.         } else {
  1000.           HT_REQUEST_START;
  1001.           HT_PRINT("There is an index.html in the directory ");
  1002.           HT_PRINT(httrack.path_log);
  1003.           HT_PRINT(" but no cache"LF);
  1004.           HT_PRINT("There is an index.html in the directory, but no cache"LF);
  1005.           HT_PRINT("A site may have been mirrored here, and erased.."LF);
  1006.           HT_PRINT("Be sure parameters are ok"LF);
  1007.           HT_REQUEST_END;
  1008.           if (!ask_continue()) {
  1009.             htsmain_free();
  1010.             return 0;
  1011.           }
  1012.         }
  1013.       }
  1014.     }
  1015.   }
  1016.   
  1017.   
  1018.   // Treat parameters
  1019.   // Traiter les paramΦtres
  1020. #if DEBUG_STEPS
  1021.   printf("Analyze parameters\n");
  1022. #endif
  1023.   { 
  1024.     char* com;
  1025.     int na;
  1026.     
  1027.     for(na=1;na<argc;na++) {
  1028.  
  1029.       if (argv[na][0]=='"') {
  1030.         char tempo[HTS_CDLMAXSIZE];
  1031.         strcpybuff(tempo,argv[na]+1);
  1032.         if (tempo[strlen(tempo)-1]!='"') {
  1033.           char s[HTS_CDLMAXSIZE];
  1034.           sprintf(s,"Missing quote in %s",argv[na]);
  1035.           HTS_PANIC_PRINTF(s);
  1036.           htsmain_free();
  1037.           return -1;
  1038.         }
  1039.         tempo[strlen(tempo)-1]='\0';
  1040.         strcpybuff(argv[na],tempo);
  1041.       }
  1042.  
  1043.       if (cmdl_opt(argv[na])) { // option
  1044.         com=argv[na]+1;
  1045.         
  1046.         while(*com) {
  1047.           switch(*com) {
  1048.           case ' ': case 9: case '-': case '\0': break;
  1049.             //
  1050.           case 'h': 
  1051.             help(argv[0],0); 
  1052.             htsmain_free();
  1053.             return 0;   // dΘja fait normalement
  1054.             //
  1055.           case 'g':    // rΘcupΘrer un (ou plusieurs) fichiers isolΘs
  1056.             httrack.wizard=2;             // le wizard on peut plus s'en passer..
  1057.             //httrack.wizard=0;             // pas de wizard
  1058.             httrack.cache=0;              // ni de cache
  1059.             httrack.makeindex=0;          // ni d'index
  1060.             httrack_logmode=1;            // erreurs α l'Θcran
  1061.             httrack.savename_type=1003;   // mettre dans le rΘpertoire courant
  1062.             httrack.depth=0;              // ne pas explorer la page
  1063.             httrack.accept_cookie=0;      // pas de cookies
  1064.             httrack.robots=0;             // pas de robots
  1065.             break;
  1066.           case 'w': httrack.wizard=2;    // wizard 'soft' (ne pose pas de questions)
  1067.             httrack.travel=0;
  1068.             httrack.seeker=1;
  1069.             break;
  1070.           case 'W': httrack.wizard=1;    // Wizard-Help (pose des questions)
  1071.             httrack.travel=0;
  1072.             httrack.seeker=1;
  1073.             break;
  1074.           case 'r':                      // n'est plus le recurse get bestial mais wizard itou!
  1075.             if (isdigit((unsigned char)*(com+1))) {
  1076.               sscanf(com+1,"%d",&httrack.depth);
  1077.               while(isdigit((unsigned char)*(com+1))) com++;
  1078.             } else httrack.depth=3;
  1079.             break;
  1080. /*
  1081.           case 'r': httrack.wizard=0;
  1082.             if (isdigit((unsigned char)*(com+1))) {
  1083.               sscanf(com+1,"%d",&httrack.depth);
  1084.               while(isdigit((unsigned char)*(com+1))) com++;
  1085.             } else httrack.depth=3;
  1086.             break;
  1087. */
  1088.             //
  1089.             // note: les tests httrack.depth sont pour Θviter de faire
  1090.             // un miroir du web (:-O) accidentelement ;-)
  1091.           case 'a': /*if (httrack.depth==9999) httrack.depth=3;*/
  1092.             httrack.travel=0+(httrack.travel&256); break;
  1093.           case 'd': /*if (httrack.depth==9999) httrack.depth=3;*/
  1094.             httrack.travel=1+(httrack.travel&256); break;
  1095.           case 'l': /*if (httrack.depth==9999) httrack.depth=3;*/
  1096.             httrack.travel=2+(httrack.travel&256); break;
  1097.           case 'e': /*if (httrack.depth==9999) httrack.depth=3;*/
  1098.             httrack.travel=7+(httrack.travel&256); break;
  1099.           case 't': httrack.travel|=256; break;
  1100.           case 'n': httrack.nearlink=1; break;
  1101.           case 'x': httrack.external=1; break;
  1102.             //
  1103.           case 'U': httrack.seeker=2; break;
  1104.           case 'D': httrack.seeker=1; break;
  1105.           case 'S': httrack.seeker=0; break;
  1106.           case 'B': httrack.seeker=3; break;
  1107.             //
  1108.           case 'Y': httrack.mirror_first_page=1; break;
  1109.             //
  1110.           case 'q': case 'i': httrack.quiet=1; break;
  1111.             //
  1112.           case 'Q': httrack_logmode=0; break;
  1113.           case 'v': httrack_logmode=1; break;
  1114.           case 'f': httrack_logmode=2; if (*(com+1)=='2') httrack_logmode=3; while(isdigit((unsigned char)*(com+1))) com++; break;
  1115.             //
  1116.           //case 'A': httrack.urlmode=1; break;
  1117.           //case 'R': httrack.urlmode=2; break;
  1118.           case 'K': httrack.urlmode=0; 
  1119.             if (isdigit((unsigned char)*(com+1))) {
  1120.               sscanf(com+1,"%d",&httrack.urlmode);
  1121.               if (httrack.urlmode == 0) {  // in fact K0 ==> K2
  1122.                                            // and K ==> K0
  1123.                 httrack.urlmode=2;
  1124.               }
  1125.               while(isdigit((unsigned char)*(com+1))) com++; 
  1126.             }
  1127.             //if (*(com+1)=='0') { httrack.urlmode=2; com++; } break;
  1128.             //
  1129.           case 'c':
  1130.             if (isdigit((unsigned char)*(com+1))) {
  1131.               sscanf(com+1,"%d",&httrack.maxsoc);
  1132.               while(isdigit((unsigned char)*(com+1))) com++;
  1133.               httrack.maxsoc=max(httrack.maxsoc,1);     // FORCER A 1
  1134.             } else httrack.maxsoc=4;
  1135.             
  1136.             break;
  1137.             //
  1138.           case 'p': sscanf(com+1,"%d",&httrack.getmode); while(isdigit((unsigned char)*(com+1))) com++; break;
  1139.             //        
  1140.           case 'G': sscanf(com+1,LLintP,&httrack.fragment); while(isdigit((unsigned char)*(com+1))) com++; break;
  1141.           case 'M': sscanf(com+1,LLintP,&httrack.maxsite); while(isdigit((unsigned char)*(com+1))) com++; break;
  1142.           case 'm': sscanf(com+1,LLintP,&httrack.maxfile_nonhtml); while(isdigit((unsigned char)*(com+1))) com++; 
  1143.             if (*(com+1)==',') {
  1144.               com++;
  1145.               sscanf(com+1,LLintP,&httrack.maxfile_html); while(isdigit((unsigned char)*(com+1))) com++;
  1146.             } else httrack.maxfile_html=-1;
  1147.             break;
  1148.             //
  1149.           case 'T': sscanf(com+1,"%d",&httrack.timeout); while(isdigit((unsigned char)*(com+1))) com++; break;
  1150.           case 'J': sscanf(com+1,"%d",&httrack.rateout); while(isdigit((unsigned char)*(com+1))) com++; break;
  1151.           case 'R': sscanf(com+1,"%d",&httrack.retry); while(isdigit((unsigned char)*(com+1))) com++; break;
  1152.           case 'E': sscanf(com+1,"%d",&httrack.maxtime); while(isdigit((unsigned char)*(com+1))) com++; break;
  1153.           case 'H': sscanf(com+1,"%d",&httrack.hostcontrol); while(isdigit((unsigned char)*(com+1))) com++; break;
  1154.           case 'A': sscanf(com+1,"%d",&httrack.maxrate); while(isdigit((unsigned char)*(com+1))) com++; break;
  1155.  
  1156.           case 'j': httrack.parsejava=1; if (*(com+1)=='0') { httrack.parsejava=0; com++; } break;
  1157.             //
  1158.           case 'I': httrack.makeindex=1; if (*(com+1)=='0') { httrack.makeindex=0; com++; } break;
  1159.             //
  1160.           case 'X': httrack.delete_old=1; if (*(com+1)=='0') { httrack.delete_old=0; com++; } break;
  1161.             //
  1162.           case 'b': sscanf(com+1,"%d",&httrack.accept_cookie); while(isdigit((unsigned char)*(com+1))) com++; break;
  1163.             //
  1164.           case 'N':
  1165.             if (strcmp(argv[na],"-N")==0) {    // Tout seul
  1166.               if ((na+1>=argc) || (argv[na+1][0]=='-')) {  // erreur
  1167.                 HTS_PANIC_PRINTF("Option N needs a number, or needs to be followed by a blank space, and a string");
  1168.                 printf("Example: -N4\n");
  1169.                 htsmain_free();
  1170.                 return -1;
  1171.               } else {
  1172.                 na++;
  1173.                 if (strlen(argv[na])>=127) {
  1174.                   HTS_PANIC_PRINTF("Userdef structure string too long");
  1175.                   htsmain_free();
  1176.                   return -1;
  1177.                 }
  1178.                 strcpybuff(httrack.savename_userdef,argv[na]);
  1179.                 if (strnotempty(httrack.savename_userdef))
  1180.                   httrack.savename_type = -1;    // userdef!
  1181.                 else
  1182.                   httrack.savename_type = 0;    // -N "" : par dΘfaut
  1183.               }
  1184.             } else {
  1185.               sscanf(com+1,"%d",&httrack.savename_type); while(isdigit((unsigned char)*(com+1))) com++;
  1186.             }
  1187.             break;
  1188.           case 'L': 
  1189.             {
  1190.               sscanf(com+1,"%d",&httrack.savename_83); 
  1191.               switch(httrack.savename_83) {
  1192.               case 0:
  1193.                 httrack.savename_83=1;
  1194.                 break;
  1195.               case 1:
  1196.                 httrack.savename_83=0;
  1197.                 break;
  1198.               default:
  1199.                 httrack.savename_83=2;
  1200.                 break;
  1201.               }
  1202.               while(isdigit((unsigned char)*(com+1))) com++; 
  1203.             }
  1204.             break;
  1205.           case 's': 
  1206.             if (isdigit((unsigned char)*(com+1))) {
  1207.               sscanf(com+1,"%d",&httrack.robots);
  1208.               while(isdigit((unsigned char)*(com+1))) com++;
  1209.             } else httrack.robots=1;
  1210. #if DEBUG_ROBOTS
  1211.             printf("robots.txt mode set to %d\n",httrack.robots);
  1212. #endif
  1213.             break;
  1214.           case 'o': sscanf(com+1,"%d",&httrack.errpage); while(isdigit((unsigned char)*(com+1))) com++; break;
  1215.           case 'u': sscanf(com+1,"%d",&httrack.check_type); while(isdigit((unsigned char)*(com+1))) com++; break;
  1216.             //
  1217.           case 'C': 
  1218.             if (isdigit((unsigned char)*(com+1))) {
  1219.               sscanf(com+1,"%d",&httrack.cache);
  1220.               while(isdigit((unsigned char)*(com+1))) com++;
  1221.             } else httrack.cache=1;
  1222.             break;
  1223.           case 'k': httrack.all_in_cache=1; break;
  1224.             //
  1225.           case 'z': httrack.debug=1; break;  // petit debug
  1226.           case 'Z': httrack.debug=2; break;  // GROS debug
  1227.             //
  1228.           case '&': case '%': {    // deuxiΦme jeu d'options
  1229.             com++;
  1230.             switch(*com) {
  1231.             case 'M': httrack.mimehtml = 1; if (*(com+1)=='0') { httrack.mimehtml=0; com++; } break;
  1232.             case 'k': httrack.nokeepalive = 0; if (*(com+1)=='0') { httrack.nokeepalive = 1; com++; } break;
  1233.             case 'x': httrack.passprivacy=1; if (*(com+1)=='0') { httrack.passprivacy=0; com++; } break;   // No passwords in html files
  1234.             case 'q': httrack.includequery=1; if (*(com+1)=='0') { httrack.includequery=0; com++; } break;   // No passwords in html files
  1235.             case 'I': httrack.kindex=1; if (isdigit((unsigned char)*(com+1))) { sscanf(com+1,"%d",&httrack.kindex); while(isdigit((unsigned char)*(com+1))) com++; }
  1236.               break;    // Keyword Index
  1237.             case 'c': sscanf(com+1,"%d",&httrack.maxconn); while(isdigit((unsigned char)*(com+1))) com++; break;
  1238.             case 'e': sscanf(com+1,"%d",&httrack.extdepth); while(isdigit((unsigned char)*(com+1))) com++; break;
  1239.             case 'B': httrack.tolerant=1; if (*(com+1)=='0') { httrack.tolerant=0; com++; } break;   // HTTP/1.0 notamment
  1240.             case 'h': httrack.http10=1; if (*(com+1)=='0') { httrack.http10=0; com++; } break;   // HTTP/1.0
  1241.             case 'z': httrack.nocompression=1; if (*(com+1)=='0') { httrack.nocompression=0; com++; } break;   // pas de compression
  1242.             case 'f': httrack.ftp_proxy=1; if (*(com+1)=='0') { httrack.ftp_proxy=0; com++; } break;   // proxy http pour ftp
  1243.             case 'P': httrack.parseall=1; if (*(com+1)=='0') { httrack.parseall=0; com++; } break;   // tout parser
  1244.             case 'n': httrack.norecatch=1; if (*(com+1)=='0') { httrack.norecatch=0; com++; } break;   // ne pas reprendre fichiers effacΘs localement
  1245.             case 's': httrack.sizehack=1; if (*(com+1)=='0') { httrack.sizehack=0; com++; } break;   // hack sur content-length
  1246.             case 'u': httrack.urlhack=1; if (*(com+1)=='0') { httrack.urlhack=0; com++; } break;   // url hack
  1247.             case 'v': httrack.verbosedisplay=2; if (isdigit((unsigned char)*(com+1))) { sscanf(com+1,"%d",&httrack.verbosedisplay); while(isdigit((unsigned char)*(com+1))) com++; } break;
  1248.             case 'i': httrack.dir_topindex = 1; if (*(com+1)=='0') { httrack.dir_topindex=0; com++; } break;
  1249.  
  1250.             // preserve: no footer, original links
  1251.             case 'p':
  1252.               httrack.footer[0]='\0';
  1253.               httrack.urlmode=4;
  1254.               break;
  1255.             case 'L':    // URL list
  1256.               if ((na+1>=argc) || (argv[na+1][0]=='-')) {
  1257.                 HTS_PANIC_PRINTF("Option %L needs to be followed by a blank space, and a text filename");
  1258.                 printf("Example: -%%L \"mylist.txt\"\n");
  1259.                 htsmain_free();
  1260.                 return -1;
  1261.               } else{
  1262.                 na++;
  1263.                 if (strlen(argv[na])>=254) {
  1264.                   HTS_PANIC_PRINTF("File list string too long");
  1265.                   htsmain_free();
  1266.                   return -1;
  1267.                 }
  1268.                 strcpybuff(httrack.filelist,argv[na]);
  1269.               }
  1270.               break;
  1271.             case 'b':  // bind
  1272.               if ((na+1>=argc) || (argv[na+1][0]=='-')) {
  1273.                 HTS_PANIC_PRINTF("Option %b needs to be followed by a blank space, and a local hostname");
  1274.                 printf("Example: -%%b \"ip4.localhost\"\n");
  1275.                 htsmain_free();
  1276.                 return -1;
  1277.               } else{
  1278.                 na++;
  1279.                 if (strlen(argv[na])>=254) {
  1280.                   HTS_PANIC_PRINTF("Hostname string too long");
  1281.                   htsmain_free();
  1282.                   return -1;
  1283.                 }
  1284.                 strcpybuff(httrack.proxy.bindhost,argv[na]);
  1285.               }
  1286.               break;
  1287.             case 'S':    // Scan Rules list
  1288.               if ((na+1>=argc) || (argv[na+1][0]=='-')) {
  1289.                 HTS_PANIC_PRINTF("Option %S needs to be followed by a blank space, and a text filename");
  1290.                 printf("Example: -%%S \"myfilterlist.txt\"\n");
  1291.                 htsmain_free();
  1292.                 return -1;
  1293.               } else{
  1294.                 INTsys fz;
  1295.                 na++;
  1296.                 fz = fsize(argv[na]);
  1297.                 if (fz < 0) {
  1298.                   HTS_PANIC_PRINTF("File url list could not be opened");
  1299.                   htsmain_free();
  1300.                   return -1;
  1301.                 } else {
  1302.                   FILE* fp = fopen(argv[na], "rb");
  1303.                   if (fp != NULL) {
  1304.                     int cl = (int) strlen(url);
  1305.                     ensureUrlCapacity(url, url_sz, cl + fz + 8192);
  1306.                     if ((INTsys)fread(url + cl, 1, fz, fp) != fz) {
  1307.                       HTS_PANIC_PRINTF("File url list could not be read");
  1308.                       htsmain_free();
  1309.                       return -1;
  1310.                     }
  1311.                     fclose(fp);
  1312.                     *(url + cl + fz) = '\0';
  1313.                   }
  1314.                 }
  1315.               }
  1316.               break;
  1317.             case 'A':    // assume
  1318.               if ((na+1>=argc) || (argv[na+1][0]=='-')) {
  1319.                 HTS_PANIC_PRINTF("Option %A needs to be followed by a blank space, and a filesystemtype=mimetype/mimesubtype parameters");
  1320.                 printf("Example: -%%A php3=text/html,asp=text/html\n");
  1321.                 htsmain_free();
  1322.                 return -1;
  1323.               } else{
  1324.                 char* a;
  1325.                 na++;
  1326.                 if ( (strlen(argv[na]) + strlen(httrack.mimedefs) + 4) >= sizeof(httrack.mimedefs)) {
  1327.                   HTS_PANIC_PRINTF("Mime definition string too long");
  1328.                   htsmain_free();
  1329.                   return -1;
  1330.                 }
  1331.                 // --assume standard
  1332.                 if (strcmp(argv[na],"standard") == 0) {
  1333.                   strcpybuff(httrack.mimedefs,"\n");
  1334.                   strcatbuff(httrack.mimedefs,HTS_ASSUME_STANDARD);
  1335.                   strcatbuff(httrack.mimedefs,"\n");
  1336.                 } else {
  1337.                   strcatbuff(httrack.mimedefs,argv[na]);
  1338.                   strcatbuff(httrack.mimedefs,"\n");
  1339.                 }
  1340.                 a=httrack.mimedefs;
  1341.                 while(*a) {
  1342.                   switch(*a) {
  1343.                   case ',': case ' ': case '\r': case ';': case '\t':
  1344.                     *a='\n';
  1345.                     break;
  1346.                   }
  1347.                   a++;
  1348.                 }
  1349.               }
  1350.               break;
  1351.               //
  1352.             case 'l': 
  1353.               if ((na+1>=argc) || (argv[na+1][0]=='-')) {
  1354.                 HTS_PANIC_PRINTF("Option %l needs to be followed by a blank space, and an ISO language code");
  1355.                 printf("Example: -%%l \"en\"\n");
  1356.                 htsmain_free();
  1357.                 return -1;
  1358.               } else{
  1359.                 na++;
  1360.                 if (strlen(argv[na])>=62) {
  1361.                   HTS_PANIC_PRINTF("Lang list string too long");
  1362.                   htsmain_free();
  1363.                   return -1;
  1364.                 }
  1365.                 strcpybuff(httrack.lang_iso,argv[na]);
  1366.               }
  1367.               break;
  1368.               //
  1369.             case 'F':     // footer id
  1370.               if ((na+1>=argc) || (argv[na+1][0]=='-')) {
  1371.                 HTS_PANIC_PRINTF("Option %F needs to be followed by a blank space, and a footer string");
  1372.                 printf("Example: -%%F \"<!-- Mirrored from %%s by HTTrack Website Copier/"HTTRACK_AFF_VERSION" "HTTRACK_AFF_AUTHORS", %%s -->\"\n");
  1373.                 htsmain_free();
  1374.                 return -1;
  1375.               } else{
  1376.                 na++;
  1377.                 if (strlen(argv[na])>=254) {
  1378.                   HTS_PANIC_PRINTF("Footer string too long");
  1379.                   htsmain_free();
  1380.                   return -1;
  1381.                 }
  1382.                 strcpybuff(httrack.footer,argv[na]);
  1383.               }
  1384.               break;
  1385.             case 'H':                 // debug headers
  1386.               _DEBUG_HEAD=1;
  1387.               break;
  1388.             case 'O':
  1389. #if HTS_WIN
  1390.               printf("Warning option -%%O has no effect in this system (chroot)\n");
  1391. #else
  1392.               switch_chroot=1;
  1393. #endif
  1394.               break;
  1395.             case 'U':                 // setuid
  1396.               if ((na+1>=argc) || (argv[na+1][0]=='-')) {
  1397.                 HTS_PANIC_PRINTF("Option %U needs to be followed by a blank space, and a username");
  1398.                 printf("Example: -%%U smith\n");
  1399.                 htsmain_free();
  1400.                 return -1;
  1401.               } else {
  1402.                 na++;
  1403. #if HTS_WIN
  1404.                 printf("Warning option -%%U has no effect on this system (setuid)\n");
  1405. #else
  1406. #ifndef HTS_DO_NOT_USE_UID
  1407.                 /* Change the user id and gid */
  1408.                 {
  1409.                   struct passwd* userdef=getpwnam((const char*)argv[na]);
  1410.                   if (userdef) {    /* we'll have to switch the user id */
  1411.                     switch_gid=userdef->pw_gid;
  1412.                     switch_uid=userdef->pw_uid;
  1413.                   }
  1414.                 }
  1415. #else
  1416.                 printf("Warning option -%%U has no effect with this compiled version (setuid)\n");
  1417. #endif
  1418. #endif
  1419.               }
  1420.               break;
  1421.               
  1422.             case 'W':       // Wrapper callback
  1423.               // --wrapper check-link=obj.so:check_link
  1424.               if ((na+1>=argc) || (argv[na+1][0]=='-')) {
  1425.                 HTS_PANIC_PRINTF("Option %W needs to be followed by a blank space, and a <callback-name>=<myfile.so>:<function-name> field");
  1426.                 printf("Example: -%%W check-link=checklink.so:check\n");
  1427.                 htsmain_free();
  1428.                 return -1;
  1429.               } else {
  1430.                 char callbackname[128];
  1431.                 char* a = argv[na + 1];
  1432.                 char* pos = strchr(a, '=');
  1433.                 na++;
  1434.                 if (pos != NULL && (pos - a) > 0 && (pos - a + 2) < sizeof(callbackname)) {
  1435.                   char* posf = strchr(pos + 1, ':');
  1436.                   char filename[1024];
  1437.                   callbackname[0] = '\0';
  1438.                   strncatbuff(callbackname, a, pos - a);
  1439.                   pos++;
  1440.                   if (posf != NULL && (posf - pos) > 0 && (posf - pos + 2) < sizeof(filename)) {
  1441.                     void* userfunction;
  1442.                     filename[0] = '\0';
  1443.                     strncatbuff(filename, pos, posf - pos);
  1444.                     posf++;
  1445.                     userfunction = getFunctionPtr(filename, posf);
  1446.                     if (userfunction != NULL) {
  1447.                       if ((void*)htswrap_read(callbackname) != NULL) {
  1448.                         if (htswrap_add(callbackname, userfunction)) {
  1449.                           if (!httrack.quiet) {
  1450.                             set_wrappers();
  1451.                             if ((void*)htswrap_read(callbackname) == userfunction) {
  1452.                               printf("successfully plugged [%s -> %s:%s]\n", callbackname, posf, filename);
  1453.                             } else {
  1454.                               char tmp[1024 * 2];
  1455.                               sprintf(tmp, "option %%W : unable to (re)plug the function %s from the file %s for the callback %s", posf, filename, callbackname);
  1456.                               HTS_PANIC_PRINTF(tmp);
  1457.                               htsmain_free();
  1458.                               return -1;
  1459.                             }
  1460.                           }
  1461.                         } else {
  1462.                           char tmp[1024 * 2];
  1463.                           sprintf(tmp, "option %%W : unable to plug the function %s from the file %s for the callback %s", posf, filename, callbackname);
  1464.                           HTS_PANIC_PRINTF(tmp);
  1465.                           htsmain_free();
  1466.                           return -1;
  1467.                         }
  1468.                       } else {
  1469.                         char tmp[1024 * 2];
  1470.                         sprintf(tmp, "option %%W : unknown or undefined callback %s", callbackname);
  1471.                         HTS_PANIC_PRINTF(tmp);
  1472.                         htsmain_free();
  1473.                         return -1;
  1474.                       }
  1475.                     } else {
  1476.                       char tmp[1024 * 2];
  1477.                       sprintf(tmp, "option %%W : unable to load the function %s in the file %s for the callback %s", posf, filename, callbackname);
  1478.                       HTS_PANIC_PRINTF(tmp);
  1479.                       htsmain_free();
  1480.                       return -1;
  1481.                     }
  1482.                   } else {
  1483.                     HTS_PANIC_PRINTF("Syntax error in option %W : filename error : this function needs to be followed by a blank space, and a <callback-name>=<myfile.so>:<function-name> field");
  1484.                     printf("Example: -%%W check-link=checklink.so:check\n");
  1485.                     htsmain_free();
  1486.                     return -1;
  1487.                   }
  1488.                 } else {
  1489.                   HTS_PANIC_PRINTF("Syntax error in option %W : this function needs to be followed by a blank space, and a <callback-name>=<myfile.so>:<function-name> field");
  1490.                   printf("Example: -%%W check-link=checklink.so:check\n");
  1491.                   htsmain_free();
  1492.                   return -1;
  1493.                 }
  1494.               }
  1495.               break;
  1496.               
  1497.             default: {
  1498.               char s[HTS_CDLMAXSIZE];
  1499.               sprintf(s,"invalid option %%%c\n",*com);
  1500.               HTS_PANIC_PRINTF(s);
  1501.               htsmain_free();
  1502.               return -1;
  1503.                      }
  1504.               break;
  1505.               
  1506.             }
  1507.                     }
  1508.             break;
  1509.             //
  1510.           case '@': {    // troisiΦme jeu d'options
  1511.             com++;
  1512.             switch(*com) {
  1513.             case 'i': 
  1514. #if HTS_INET6==0
  1515.               printf("Warning, option @i has no effect (v6 routines not compiled)\n");
  1516. #else 
  1517.               {
  1518.                 int res=0;
  1519.                 if (isdigit((unsigned char)*(com+1))) {
  1520.                   sscanf(com+1,"%d",&res); while(isdigit((unsigned char)*(com+1))) com++; 
  1521.                 }
  1522.                 switch(res) {
  1523.                 case 1:
  1524.                 case 4:
  1525.                   IPV6_resolver=1;
  1526.                   break;
  1527.                 case 2:
  1528.                 case 6:
  1529.                   IPV6_resolver=2;
  1530.                   break;
  1531.                 case 0:
  1532.                   IPV6_resolver=0;
  1533.                   break;
  1534.                 default:
  1535.                   printf("Unknown flag @i%d\n", res);
  1536.                   htsmain_free();
  1537.                   return -1;
  1538.                   break;
  1539.                 }
  1540.               }
  1541. #endif
  1542.               break;
  1543.               
  1544.                 default: {
  1545.                   char s[HTS_CDLMAXSIZE];
  1546.                   sprintf(s,"invalid option %%%c\n",*com);
  1547.                   HTS_PANIC_PRINTF(s);
  1548.                   htsmain_free();
  1549.                   return -1;
  1550.                          }
  1551.                   break;
  1552.                   
  1553.                   //case 's': httrack.sslengine=1; if (isdigit((unsigned char)*(com+1))) { sscanf(com+1,"%d",&httrack.sslengine); while(isdigit((unsigned char)*(com+1))) com++; } break;
  1554.             }
  1555.                     }
  1556.             break;
  1557.             
  1558.             //
  1559.           case '#':  { // non documentΘ
  1560.             com++;
  1561.             switch(*com) {
  1562.             case 'C':   // list cache files : httrack -#C '*spid*.gif' will attempt to find the matching file
  1563.               {
  1564.                 int hasFilter = 0;
  1565.                 int found = 0;
  1566.                 char* filter=NULL;
  1567.                 cache_back cache;
  1568.                 inthash cache_hashtable=inthash_new(HTS_HASH_SIZE);
  1569.                 int backupXFR = htsMemoryFastXfr;
  1570.                 int sendb = 0;
  1571.                 if (isdigit((unsigned char)*(com+1))) {
  1572.                   sscanf(com+1,"%d",&sendb);
  1573.                   while(isdigit((unsigned char)*(com+1))) com++;
  1574.                 } else sendb=0;
  1575.                 if (!((na+1>=argc) || (argv[na+1][0]=='-'))) {
  1576.                   na++;
  1577.                   hasFilter = 1;
  1578.                   filter=argv[na];
  1579.                 }
  1580.                 htsMemoryFastXfr = 1;               /* fast load */
  1581.  
  1582.                 memset(&cache, 0, sizeof(cache_back));
  1583.                 cache.type=1;       // cache?
  1584.                 cache.log=stdout;     // log?
  1585.                 cache.errlog=stderr;  // err log?
  1586.                 cache.ptr_ant=cache.ptr_last=0;   // pointeur pour anticiper
  1587.                 cache.hashtable=(void*)cache_hashtable;      /* copy backcache hash */
  1588.                 cache.ro = 1;          /* read only */
  1589.                 if (cache.hashtable) {
  1590.                   char adr[HTS_URLMAXSIZE*2];
  1591.                   char fil[HTS_URLMAXSIZE*2];
  1592.                   char url[HTS_URLMAXSIZE*2];
  1593.                   char linepos[256];
  1594.                   int  pos;
  1595.                   char* cacheNdx = readfile(fconcat(httrack.path_log,"hts-cache/new.ndx"));
  1596.                   cache_init(&cache,&httrack);            /* load cache */
  1597.                   if (cacheNdx != NULL) {
  1598.                     char firstline[256];
  1599.                     char* a = cacheNdx;
  1600.                     a+=cache_brstr(a, firstline);
  1601.                     a+=cache_brstr(a, firstline);
  1602.                     while ( a != NULL ) {
  1603.                       a=strchr(a+1,'\n');     /* start of line */
  1604.                       if (a) {
  1605.                         htsblk r;
  1606.                         /* */
  1607.                         a++;
  1608.                         /* read "host/file" */
  1609.                         a+=binput(a,adr,HTS_URLMAXSIZE);
  1610.                         a+=binput(a,fil,HTS_URLMAXSIZE);
  1611.                         url[0]='\0';
  1612.                         if (!link_has_authority(adr))
  1613.                           strcatbuff(url, "http://");
  1614.                         strcatbuff(url, adr);
  1615.                         strcatbuff(url, fil);
  1616.                         /* read position */
  1617.                         a+=binput(a,linepos,200);
  1618.                         sscanf(linepos,"%d",&pos);
  1619.                         if (!hasFilter
  1620.                           ||
  1621.                           (strjoker(url, filter, NULL, NULL) != NULL)
  1622.                           ) {
  1623.                           r = cache_read(&httrack, &cache, adr, fil, "", NULL);    // lire entrΘe cache + data
  1624.                           if (r.statuscode != -1) {    // No errors
  1625.                             found++;
  1626.                             if (!hasFilter) {
  1627.                               fprintf(stdout, "%s%s%s\r\n", 
  1628.                                 (link_has_authority(adr)) ? "" : "http://", 
  1629.                                 adr, fil);
  1630.                             } else {
  1631.                               char msg[256], cdate[256];
  1632.                               char sav[HTS_URLMAXSIZE*2];
  1633.                               infostatuscode(msg, r.statuscode);
  1634.                               time_gmt_rfc822(cdate);
  1635.  
  1636.                               fprintf(stdout, "HTTP/1.1 %d %s\r\n",
  1637.                                 r.statuscode,
  1638.                                 r.msg[0] ? r.msg : msg
  1639.                                 );
  1640.                               fprintf(stdout, "X-Host: %s\r\n", adr);
  1641.                               fprintf(stdout, "X-File: %s\r\n", fil);
  1642.                               fprintf(stdout, "X-URL: %s%s%s\r\n", 
  1643.                                 (link_has_authority(adr)) ? "" : "http://", 
  1644.                                 adr, fil);
  1645.                               if (url_savename(adr, fil, sav, NULL, NULL, NULL, NULL,
  1646.                                 &httrack, NULL, 0, NULL, 0, &cache, NULL, 0, 0)!=-1) {
  1647.                                 if (fexist(sav)) {
  1648.                                   fprintf(stdout, "Content-location: %s\r\n", sav);
  1649.                                 }
  1650.                               }
  1651.                               fprintf(stdout, "Date: %s\r\n", cdate);
  1652.                               fprintf(stdout, "Server: HTTrack Website Copier/"HTTRACK_VERSION"\r\n");
  1653.                               if (r.lastmodified[0]) {
  1654.                                 fprintf(stdout, "Last-Modified: %s\r\n", r.lastmodified);
  1655.                               }
  1656.                               if (r.etag[0]) {
  1657.                                 fprintf(stdout, "Etag: %s\r\n", r.etag);
  1658.                               }
  1659.                               if (r.totalsize >= 0) {
  1660.                                 fprintf(stdout, "Content-Length: "LLintP"\r\n", r.totalsize);
  1661.                               }
  1662.                               fprintf(stdout, "X-Content-Length: "LLintP"\r\n", (r.size >= 0) ? r.size : (-r.size) );
  1663.                               if (r.contenttype >= 0) {
  1664.                                 fprintf(stdout, "Content-Type: %s\r\n", r.contenttype);
  1665.                               }
  1666.                               if (r.cdispo[0]) {
  1667.                                 fprintf(stdout, "Content-Disposition: %s\r\n", r.cdispo);
  1668.                               }
  1669.                               if (r.contentencoding[0]) {
  1670.                                 fprintf(stdout, "Content-Encoding: %s\r\n", r.contentencoding);
  1671.                               }
  1672.                               if (r.is_chunk) {
  1673.                                 fprintf(stdout, "Transfer-Encoding: chunked\r\n");
  1674.                               }
  1675. #if HTS_USEOPENSSL
  1676.                               if (r.ssl) {
  1677.                                 fprintf(stdout, "X-SSL: yes\r\n");
  1678.                               }
  1679. #endif
  1680.                               if (r.is_write) {
  1681.                                 fprintf(stdout, "X-Direct-To-Disk: yes\r\n");
  1682.                               }
  1683.                               if (r.compressed) {
  1684.                                 fprintf(stdout, "X-Compressed: yes\r\n");
  1685.                               }
  1686.                               if (r.notmodified) {
  1687.                                 fprintf(stdout, "X-Not-Modified: yes\r\n");
  1688.                               }
  1689.                               if (r.is_chunk) {
  1690.                                 fprintf(stdout, "X-Chunked: yes\r\n");
  1691.                               }
  1692.                               fprintf(stdout, "\r\n");
  1693.                               /* Send the body */
  1694.                               if (sendb && r.adr) {
  1695.                                 fprintf(stdout, "%s\r\n", r.adr);
  1696.                               }
  1697.                             }
  1698.                           }
  1699.                         }
  1700.                       }
  1701.                     }
  1702.                     freet(cacheNdx);
  1703.                   }
  1704.                 }
  1705.                 if (!found) {
  1706.                   fprintf(stderr, "No cache entry found%s%s%s\r\n",
  1707.                     (hasFilter)?" for '":"",
  1708.                     (hasFilter)?filter:"",
  1709.                     (hasFilter)?"'":""
  1710.                     );
  1711.                 }
  1712.                 htsMemoryFastXfr = backupXFR;
  1713.                 return 0;
  1714.               }
  1715.               break;
  1716.             case 'X': 
  1717. #ifndef STRDEBUG
  1718.               fprintf(stderr, "warning: no string debugging support built, option has no effect\n");
  1719. #endif
  1720.               htsMemoryFastXfr=1; 
  1721.               if (*(com+1)=='0') { htsMemoryFastXfr=0; com++; } 
  1722.               break;
  1723.             case '~': /* internal lib test */
  1724.               {
  1725.                 char thisIsATestYouShouldSeeAnError[12];
  1726.                 strcpybuff(thisIsATestYouShouldSeeAnError, "0123456789012345678901234567890123456789");
  1727.                 return 0;
  1728.               }
  1729.               break;
  1730.             case 'f': httrack.flush=1; break;
  1731.             case 'h':
  1732.               printf("HTTrack version "HTTRACK_VERSION"%s\n", WHAT_is_available);
  1733.               return 0;
  1734.               break;
  1735.             case 'p': /* httrack.aff_progress=1; deprecated */ break;
  1736.             case 'S': httrack.shell=1; break;  // stdin sur un shell
  1737.             case 'K': httrack.keyboard=1; break;  // vΘrifier stdin
  1738.               //
  1739.             case 'L': sscanf(com+1,"%d",&httrack.maxlink); while(isdigit((unsigned char)*(com+1))) com++; break;
  1740.             case 'F': sscanf(com+1,"%d",&httrack.maxfilter); while(isdigit((unsigned char)*(com+1))) com++; break;
  1741.             case 'Z': httrack.makestat=1; break;
  1742.             case 'T': httrack.maketrack=1; break;
  1743.             case 'u': sscanf(com+1,"%d",&httrack.waittime); while(isdigit((unsigned char)*(com+1))) com++; break;
  1744.  
  1745.             case 'R':    // ohh ftp, catch->ftpget
  1746.               HTS_PANIC_PRINTF("Unexpected internal error with -#R command");
  1747.               htsmain_free();
  1748.               return -1;        
  1749.               break;
  1750.             case 'P': {     // catchurl
  1751.               help_catchurl(httrack.path_log);
  1752.               htsmain_free();
  1753.               return 0;
  1754.                       }
  1755.               break;
  1756.           
  1757.             case '0':   /* test #0 : filters */
  1758.               if (na+2>=argc) {
  1759.                 HTS_PANIC_PRINTF("Option #0 needs to be followed by a filter string and a string");
  1760.                 printf("Example: '-#0' '*.gif' 'foo.gif'\n");
  1761.                 htsmain_free();
  1762.                 return -1;
  1763.               } else {
  1764.                 if (strjoker(argv[na+2],argv[na+1],NULL,NULL))
  1765.                   printf("%s does match %s\n",argv[na+2],argv[na+1]);
  1766.                 else
  1767.                   printf("%s does NOT match %s\n",argv[na+2],argv[na+1]);
  1768.                 htsmain_free();
  1769.                 return 0;
  1770.               }
  1771.               break;
  1772.             case '!':
  1773.               if (na+1>=argc) {
  1774.                 HTS_PANIC_PRINTF("Option #! needs to be followed by a commandline");
  1775.                 printf("Example: '-#!' 'echo hello'\n");
  1776.                 htsmain_free();
  1777.                 return -1;
  1778.               } else {
  1779.                 system(argv[na+1]);
  1780.               }
  1781.               break;
  1782.  
  1783.             default: printf("Internal option %c not recognized\n",*com); break;
  1784.             }
  1785.                      }
  1786.             break; 
  1787.           case 'O':    // output path
  1788.             na++;     // sauter, dΘja traitΘ
  1789.             break;
  1790.           case 'P':    // proxy
  1791.             if ((na+1>=argc) || (argv[na+1][0]=='-')) {
  1792.               HTS_PANIC_PRINTF("Option P needs to be followed by a blank space, and a proxy proxy:port or user:id@proxy:port");
  1793.               printf("Example: -P proxy.myhost.com:8080\n");
  1794.               htsmain_free();
  1795.               return -1;
  1796.             } else {
  1797.               char* a;
  1798.               na++;
  1799.               httrack.proxy.active=1;
  1800.               // Rechercher MAIS en partant de la fin α cause de user:pass@proxy:port
  1801.               a = argv[na] + strlen(argv[na]) -1;
  1802.               // a=strstr(argv[na],":");  // port
  1803.               while( (a > argv[na]) && (*a != ':') && (*a != '@') ) a--;
  1804.               if (*a == ':') {  // un port est prΘsent, <proxy>:port
  1805.                 sscanf(a+1,"%d",&httrack.proxy.port);
  1806.                 httrack.proxy.name[0]='\0';
  1807.                 strncatbuff(httrack.proxy.name,argv[na],(int) (a - argv[na]));
  1808.               } else {  // <proxy>
  1809.                 httrack.proxy.port=8080;
  1810.                 strcpybuff(httrack.proxy.name,argv[na]);
  1811.               }
  1812.             }
  1813.             break;
  1814.           case 'F':    // user-agent field
  1815.             if ((na+1>=argc) || (argv[na+1][0]=='-')) {
  1816.               HTS_PANIC_PRINTF("Option F needs to be followed by a blank space, and a user-agent name");
  1817.               printf("Example: -F \"my_user_agent/1.0\"\n");
  1818.               htsmain_free();
  1819.               return -1;
  1820.             } else{
  1821.               na++;
  1822.               if (strlen(argv[na])>=126) {
  1823.                 HTS_PANIC_PRINTF("User-agent length too long");
  1824.                 htsmain_free();
  1825.                 return -1;
  1826.               }
  1827.               strcpybuff(httrack.user_agent,argv[na]);
  1828.               if (strnotempty(httrack.user_agent))
  1829.                 httrack.user_agent_send=1;
  1830.               else
  1831.                 httrack.user_agent_send=0;    // -F "" dΘsactive l'option
  1832.             }
  1833.             break;
  1834.             //
  1835.           case 'V':    // execute command
  1836.             if ((na+1>=argc) || (argv[na+1][0]=='-')) {
  1837.               HTS_PANIC_PRINTF("Option V needs to be followed by a system-command string");
  1838.               printf("Example: -V \"tar uvf some.tar \\$0\"\n");
  1839.               htsmain_free();
  1840.               return -1;
  1841.             } else{
  1842.               na++;
  1843.               if (strlen(argv[na])>=2048) {
  1844.                 HTS_PANIC_PRINTF("System-command length too long");
  1845.                 htsmain_free();
  1846.                 return -1;
  1847.               }
  1848.               strcpybuff(httrack.sys_com,argv[na]);
  1849.               if (strnotempty(httrack.sys_com))
  1850.                 httrack.sys_com_exec=1;
  1851.               else
  1852.                 httrack.sys_com_exec=0;    // -V "" dΘsactive l'option
  1853.             }
  1854.             break;
  1855.             //
  1856.           default: {
  1857.             char s[HTS_CDLMAXSIZE];
  1858.             sprintf(s,"invalid option %c\n",*com);
  1859.             HTS_PANIC_PRINTF(s);
  1860.             htsmain_free();
  1861.             return -1;
  1862.                    }
  1863.             break;
  1864.           }  // switch
  1865.           com++;    
  1866.         }  // while
  1867.         
  1868.       }  else {  // URL/filters
  1869.         char tempo[1024];       
  1870.         if (strnotempty(url)) strcatbuff(url," ");  // espace de sΘparation
  1871.         strcpybuff(tempo,unescape_http_unharm(argv[na],1));
  1872.         escape_spc_url(tempo);
  1873.         strcatbuff(url,tempo);
  1874.       }  // if argv=- etc. 
  1875.       
  1876.     }  // for
  1877.   }
  1878.   
  1879. #if BDEBUG==3  
  1880.   printf("URLs/filters=%s\n",url);
  1881. #endif
  1882.  
  1883. #if DEBUG_STEPS
  1884.   printf("Analyzing parameters done\n");
  1885. #endif
  1886.  
  1887.  
  1888. #if HTS_WIN
  1889. #else
  1890. #ifndef HTS_DO_NOT_USE_UID
  1891.   /* Chroot - xxc */
  1892.   if (switch_chroot) {
  1893.     uid_t userid=getuid();
  1894.     //struct passwd* userdef=getpwuid(userid);
  1895.     //if (userdef) {
  1896.     if (!userid) {
  1897.       //if (strcmp(userdef->pw_name,"root")==0) {
  1898.       char rpath[1024];
  1899.       //printf("html=%s log=%s\n",httrack.path_html,httrack.path_log);    // xxc
  1900.       if ((httrack.path_html[0]) && (httrack.path_log[0])) {
  1901.         char *a=httrack.path_html,*b=httrack.path_log,*c=NULL,*d=NULL;
  1902.         c=a; d=b;
  1903.         while ((*a) && (*a == *b)) {
  1904.           if (*a=='/') { c=a; d=b; }
  1905.           a++;
  1906.           b++;
  1907.         }
  1908.  
  1909.         rpath[0]='\0';
  1910.         if (c != httrack.path_html) {
  1911.           if (httrack.path_html[0]!='/')
  1912.             strcatbuff(rpath,"./");
  1913.           strncatbuff(rpath,httrack.path_html,(int) (c - httrack.path_html));
  1914.         }
  1915.         {
  1916.           char tmp[1024];
  1917.           strcpybuff(tmp,c); strcpybuff(httrack.path_html,tmp);
  1918.           strcpybuff(tmp,d); strcpybuff(httrack.path_log,tmp);
  1919.         }
  1920.       } else {
  1921.         strcpybuff(rpath,"./");
  1922.         strcpybuff(httrack.path_html,"/");
  1923.         strcpybuff(httrack.path_log,"/");
  1924.       }
  1925.       if (rpath[0]) {
  1926.         printf("[changing root path to %s (path_data=%s,path_log=%s)]\n",rpath,httrack.path_html,httrack.path_log);
  1927.         if (chroot(rpath)) {
  1928.           printf("ERROR! Can not chroot to %s!\n",rpath);
  1929.           return -1;
  1930.         }
  1931.         if (chdir("/")) {     /* new root */
  1932.           printf("ERROR! Can not chdir to %s!\n",rpath);
  1933.           return -1;
  1934.         }
  1935.       } else
  1936.         printf("WARNING: chroot not possible with these paths\n");
  1937.     }
  1938.     //}
  1939.   }
  1940.  
  1941.   /* Setuid */
  1942.   if (switch_uid>=0) {
  1943.     printf("[setting user/group to %d/%d]\n",switch_uid,switch_gid);
  1944.     if (setgid(switch_gid))
  1945.       printf("WARNING! Can not setgid to %d!\n",switch_gid);
  1946.     if (setuid(switch_uid))
  1947.       printf("WARNING! Can not setuid to %d!\n",switch_uid);
  1948.   }
  1949.  
  1950.   /* Final check */
  1951.   {
  1952.     uid_t userid=getuid();
  1953.     if (!userid) {              /* running as r00t */
  1954.       printf("WARNING! You are running this program as root!\n");
  1955.       printf("It might be a good idea to use the -%%U option to change the userid:\n");
  1956.       printf("Example: -%%U smith\n\n");
  1957.     }
  1958.   }
  1959. #endif
  1960. #endif
  1961.   
  1962.   //printf("WARNING! This is *only* a beta-release of HTTrack\n");
  1963.   io_flush;
  1964.   
  1965. #if DEBUG_STEPS
  1966.   printf("Cache & log settings\n");
  1967. #endif
  1968.   
  1969.   // on utilise le cache..
  1970.   // en cas de prΘsence des deux versions, garder la version la plus avancΘe,
  1971.   // cad la version contenant le plus de fichiers  
  1972.   if (httrack.cache) {
  1973.     if (fexist(fconcat(httrack.path_log,"hts-in_progress.lock"))) {   // problemes..
  1974.       if (fexist(fconcat(httrack.path_log,"hts-cache/new.dat")) && fexist(fconcat(httrack.path_log,"hts-cache/new.ndx"))) { 
  1975.         if (fexist(fconcat(httrack.path_log,"hts-cache/old.dat")) && fexist(fconcat(httrack.path_log,"hts-cache/old.ndx"))) {
  1976.           // switcher si new<32Ko et old>65Ko (tailles arbitraires) ?
  1977.           // ce cas est peut Ωtre une erreur ou un crash d'un miroir ancien, prendre
  1978.           // alors l'ancien cache
  1979.           if (fsize(fconcat(httrack.path_log,"hts-cache/new.dat"))<32768) {
  1980.             if (fsize(fconcat(httrack.path_log,"hts-cache/old.dat"))>65536) {
  1981.               if (fsize(fconcat(httrack.path_log,"hts-cache/old.dat")) > fsize(fconcat(httrack.path_log,"hts-cache/new.dat"))) {
  1982.                 remove(fconcat(httrack.path_log,"hts-cache/new.dat"));
  1983.                 remove(fconcat(httrack.path_log,"hts-cache/new.ndx"));
  1984.                 rename(fconcat(httrack.path_log,"hts-cache/old.dat"),fconcat(httrack.path_log,"hts-cache/new.dat"));
  1985.                 rename(fconcat(httrack.path_log,"hts-cache/old.ndx"),fconcat(httrack.path_log,"hts-cache/new.ndx"));  
  1986.                 //} else {  // ne rien faire
  1987.                 //  remove("hts-cache/old.dat");
  1988.                 //  remove("hts-cache/old.ndx");
  1989.               }
  1990.             }
  1991.           }
  1992.         }
  1993.       }
  1994.     }
  1995.   }
  1996.  
  1997.   // DΘbuggage des en tΩtes
  1998.   if (_DEBUG_HEAD) {
  1999.     ioinfo=fopen(fconcat(httrack.path_log,"hts-ioinfo.txt"),"wb");
  2000.   }
  2001.   
  2002.   {
  2003.     char n_lock[256];
  2004.     // on peut pas avoir un affichage ET un fichier log
  2005.     // ca sera pour la version 2
  2006.     if (httrack_logmode==1) {
  2007.       httrack.log=stdout;
  2008.       httrack.errlog=stderr;
  2009.     } else if (httrack_logmode>=2) {
  2010.       // deux fichiers log
  2011.       structcheck(httrack.path_log);
  2012.       if (fexist(fconcat(httrack.path_log,"hts-log.txt")))
  2013.         remove(fconcat(httrack.path_log,"hts-log.txt"));
  2014.       if (fexist(fconcat(httrack.path_log,"hts-err.txt")))
  2015.         remove(fconcat(httrack.path_log,"hts-err.txt"));
  2016.  
  2017.       /* Check FS directory structure created */
  2018.       structcheck(httrack.path_log);
  2019.  
  2020.       httrack.log=fopen(fconcat(httrack.path_log,"hts-log.txt"),"w");
  2021.       if (httrack_logmode==2)
  2022.         httrack.errlog=fopen(fconcat(httrack.path_log,"hts-err.txt"),"w");
  2023.       else
  2024.         httrack.errlog=httrack.log;
  2025.       if (httrack.log==NULL) {
  2026.         char s[HTS_CDLMAXSIZE];
  2027.         sprintf(s,"Unable to create log file %s",fconcat(httrack.path_log,"hts-log.txt"));
  2028.         HTS_PANIC_PRINTF(s);
  2029.         htsmain_free();
  2030.         return -1;
  2031.       } else if (httrack.errlog==NULL) {
  2032.         char s[HTS_CDLMAXSIZE];
  2033.         sprintf(s,"Unable to create log file %s",fconcat(httrack.path_log,"hts-err.txt"));
  2034.         HTS_PANIC_PRINTF(s);
  2035.         htsmain_free();
  2036.         return -1;
  2037.       }
  2038.  
  2039.     } else {
  2040.       httrack.log=NULL;
  2041.       httrack.errlog=NULL;
  2042.     }
  2043.     
  2044.     // un petit lock-file pour indiquer un miroir en cours, ainsi qu'un Θventuel fichier log
  2045.     {
  2046.       FILE* fp=NULL;
  2047.       //int n=0;
  2048.       char t[256];
  2049.       time_local_rfc822(t);    // faut bien que ca serve quelque part l'heure RFC1945 arf'
  2050.       
  2051.       /* readme for information purpose */
  2052.       {
  2053.         FILE* fp=fopen(fconcat(httrack.path_log,"hts-cache/readme.txt"),"wb");
  2054.         if (fp) {
  2055.           fprintf(fp,"What's in this folder?"LF);
  2056.           fprintf(fp,""LF);
  2057.           fprintf(fp,"This folder (hts-cache) has been generated by WinHTTrack "HTTRACK_VERSION"%s"LF, WHAT_is_available);
  2058.           fprintf(fp,"and is used for updating this website."LF);
  2059.           fprintf(fp,"(The HTML website structure is stored here to allow fast updates)"LF""LF);
  2060.           fprintf(fp,"DO NOT delete this folder unless you do not want to update the mirror in the future!!"LF);
  2061.           fprintf(fp,"(you can safely delete old.dat, old.ndx and old.lst files, however)"LF);
  2062.           fprintf(fp,""LF);
  2063.           fprintf(fp,HTS_LOG_SECURITY_WARNING);
  2064.           fclose(fp);
  2065.         }
  2066.       }
  2067.  
  2068.       sprintf(n_lock,fconcat(httrack.path_log,"hts-in_progress.lock"));
  2069.       //sprintf(n_lock,fconcat(httrack.path_log,"hts-in_progress.lock"),n);
  2070.       /*do {
  2071.         if (!n)
  2072.           sprintf(n_lock,fconcat(httrack.path_log,"hts-in_progress.lock"),n);
  2073.         else
  2074.           sprintf(n_lock,fconcat(httrack.path_log,"hts-in_progress%d.lock"),n);
  2075.         n++;
  2076.       } while((fexist(n_lock)) && httrack.quiet);      
  2077.       if (fexist(n_lock)) {
  2078.         if (!recuperer) {
  2079.           remove(n_lock);
  2080.         }
  2081.       }*/
  2082.  
  2083.       // vΘrifier existence de la structure
  2084.       structcheck(fconcat(httrack.path_html, "/"));
  2085.       structcheck(fconcat(httrack.path_log, "/"));
  2086.      
  2087.       // reprise/update
  2088.       if (httrack.cache) {
  2089.         FILE* fp;
  2090.         int i;
  2091. #if HTS_WIN
  2092.         mkdir(fconcat(httrack.path_log,"hts-cache"));
  2093. #else
  2094.         mkdir(fconcat(httrack.path_log,"hts-cache"),HTS_PROTECT_FOLDER);
  2095. #endif
  2096.         fp=fopen(fconcat(httrack.path_log,"hts-cache/doit.log"),"wb");
  2097.         if (fp) {
  2098.           for(i=0+1;i<argc;i++) {
  2099.             if ( ((strchr(argv[i],' ')!=NULL) || (strchr(argv[i],'"')!=NULL) || (strchr(argv[i],'\\')!=NULL)) && (argv[i][0]!='"')  ) {
  2100.               int j;
  2101.               fprintf(fp,"\"");
  2102.               for(j=0;j<(int) strlen(argv[i]);j++) {
  2103.                 if (argv[i][j]==34)
  2104.                   fprintf(fp,"\\\"");
  2105.                 else if (argv[i][j]=='\\')
  2106.                   fprintf(fp,"\\\\");
  2107.                 else
  2108.                   fprintf(fp,"%c",argv[i][j]);
  2109.               }
  2110.               fprintf(fp,"\"");
  2111.             } else if (strnotempty(argv[i])==0) {   // ""
  2112.               fprintf(fp,"\"\"");
  2113.             } else {   // non critique
  2114.               fprintf(fp,"%s",argv[i]);
  2115.             }
  2116.             if (i<argc-1)
  2117.               fprintf(fp," ");
  2118.           }
  2119.           fprintf(fp,LF);
  2120.           fprintf(fp,"File generated automatically on %s, do NOT edit"LF,t);
  2121.           fprintf(fp,LF);
  2122.           fprintf(fp,"To update a mirror, just launch httrack without any parameters"LF);
  2123.           fprintf(fp,"The existing cache will be used (and modified)"LF);
  2124.           fprintf(fp,"To have other options, retype all parameters and launch HTTrack"LF);
  2125.           fprintf(fp,"To continue an interrupted mirror, just launch httrack without any parameters"LF);
  2126.           fprintf(fp,LF);
  2127.           fclose(fp); fp=NULL;
  2128.         //} else if (httrack.debug>1) {
  2129.         //  printf("! FileOpen error, \"%s\"\n",strerror(errno));
  2130.         }
  2131.       }
  2132.       
  2133.       // petit message dans le lock
  2134.       if ( (fp=fopen(n_lock,"wb"))!=NULL) {
  2135.         int i;
  2136.         fprintf(fp,"Mirror in progress since %s .. please wait!"LF,t);
  2137.         for(i=0;i<argc;i++) {
  2138.           if (strchr(argv[i],' ')==NULL)
  2139.             fprintf(fp,"%s ",argv[i]);
  2140.           else    // entre ""
  2141.             fprintf(fp,"\"%s\" ",argv[i]);
  2142.         }
  2143.         fprintf(fp,LF);
  2144.         fprintf(fp, "To pause the engine: create an empty file named 'hts-stop.lock'"LF);
  2145.         fclose(fp); fp=NULL;
  2146.       }
  2147.       
  2148.       // fichier log        
  2149.       if (httrack.log)     {
  2150.         int i;
  2151.         fprintf(httrack.log,"HTTrack"HTTRACK_VERSION"%s launched on %s at %s"LF, 
  2152.           WHAT_is_available,
  2153.           t, url);
  2154.         fprintf(httrack.log,"(");
  2155.         for(i=0;i<argc;i++) {
  2156.           if ((strchr(argv[i],' ')==NULL) || (strchr(argv[i],'\"')))
  2157.             fprintf(httrack.log,"%s ",argv[i]);
  2158.           else    // entre "" (si espace(s) et pas dΘja de ")
  2159.             fprintf(httrack.log,"\"%s\" ",argv[i]);
  2160.         }
  2161.         fprintf(httrack.log,")"LF);
  2162.         fprintf(httrack.log,LF);
  2163.         fprintf(httrack.log,"Information, Warnings and Errors reported for this mirror:"LF);
  2164.         fprintf(httrack.log,HTS_LOG_SECURITY_WARNING );
  2165.         fprintf(httrack.log,LF);
  2166.       }
  2167.  
  2168.       if (httrack_logmode) {
  2169.         printf("Mirror launched on %s by HTTrack Website Copier/"HTTRACK_VERSION"%s "HTTRACK_AFF_AUTHORS""LF,t,WHAT_is_available);
  2170.         if (httrack.wizard==0) {
  2171.           printf("mirroring %s with %d levels, %d sockets,t=%d,s=%d,logm=%d,lnk=%d,mdg=%d\n",url,httrack.depth,httrack.maxsoc,httrack.travel,httrack.seeker,httrack_logmode,httrack.urlmode,httrack.getmode);
  2172.         } else {    // the magic wizard
  2173.           printf("mirroring %s with the wizard help..\n",url);
  2174.         }
  2175.       }
  2176.     }
  2177.     
  2178.     io_flush;
  2179.  
  2180.   /* Info for wrappers */
  2181.   if ( (httrack.debug>0) && (httrack.log!=NULL) ) {
  2182.     fspc(httrack.log,"info"); fprintf(httrack.log,"engine: init"LF);
  2183.   }
  2184. #if HTS_ANALYSTE
  2185.   hts_htmlcheck_init();
  2186. #endif
  2187.  
  2188.   // dΘtourner SIGHUP etc.
  2189. #if HTS_WIN
  2190.   signal( SIGINT  , sig_ask    );   // ^C
  2191.   signal( SIGTERM , sig_finish );   // kill <process>
  2192. #else
  2193.   signal( SIGHUP  , sig_back   );   // close window
  2194.   signal( SIGTSTP , sig_back   );   // ^Z
  2195.   signal( SIGTERM , sig_finish );   // kill <process>
  2196.   signal( SIGINT  , sig_ask    );   // ^C
  2197.   signal( SIGPIPE , sig_brpipe );   // broken pipe (write into non-opened socket)
  2198. /*
  2199. deprecated - see SIGCHLD
  2200. #ifndef HTS_DO_NOT_SIGCLD
  2201.   signal( SIGCLD  , sig_ignore );   // child change status
  2202. #endif
  2203. */
  2204.   signal( SIGCHLD , sig_ignore );   // child change status
  2205. #endif
  2206. #if DEBUG_STEPS
  2207.   printf("Launching the mirror\n");
  2208. #endif
  2209.   
  2210.  
  2211.     // Lancement du miroir
  2212.     // ------------------------------------------------------------
  2213.     if (httpmirror(url, &httrack)==0) {
  2214.       printf("Error during operation (see log file), site has not been successfully mirrored\n");
  2215.     } else {
  2216.       if  (httrack.shell) {
  2217.         HTT_REQUEST_START;
  2218.         HT_PRINT("TRANSFER DONE"LF);
  2219.         HTT_REQUEST_END
  2220.       } else {
  2221.         printf("Done.\n");
  2222.       }
  2223.     }
  2224.     // ------------------------------------------------------------
  2225.  
  2226.     //
  2227.     // Build top index
  2228.     if (httrack.dir_topindex) {
  2229.       char rpath[1024*2];
  2230.       char* a;
  2231.       strcpybuff(rpath,httrack.path_html);
  2232.       if (rpath[0]) {
  2233.         if (rpath[strlen(rpath)-1]=='/')
  2234.           rpath[strlen(rpath)-1]='\0';
  2235.       }
  2236.       a=strrchr(rpath,'/');
  2237.       if (a) {
  2238.         *a='\0';
  2239.         hts_buildtopindex(&httrack,rpath,httrack.path_bin);
  2240.         if (httrack.log) {
  2241.           fspc(httrack.log,"info"); fprintf(httrack.log,"Top index rebuilt (done)"LF);
  2242.         }
  2243.       }
  2244.     }
  2245.  
  2246.     if (exit_xh ==1) {
  2247.       if (httrack.log) {
  2248.         fprintf(httrack.log,"* * MIRROR ABORTED! * *\nThe current temporary cache is required for any update operation and only contains data downloaded during the present aborted session.\nThe former cache might contain more complete information; if you do not want to lose that information, you have to restore it and delete the current cache.\nThis can easily be done here by erasing the hts-cache/new.* files]\n");
  2249.       }
  2250.     }
  2251.  
  2252.   /* Info for wrappers */
  2253.   if ( (httrack.debug>0) && (httrack.log!=NULL) ) {
  2254.     fspc(httrack.log,"info"); fprintf(httrack.log,"engine: free"LF);
  2255.   }
  2256. #if HTS_ANALYSTE
  2257.   hts_htmlcheck_uninit();
  2258. #endif
  2259.     
  2260.     if (httrack_logmode!=1) {
  2261.       if (httrack.errlog == httrack.log) httrack.errlog=NULL;
  2262.       if (httrack.log) { fclose(httrack.log); httrack.log=NULL; }
  2263.       if (httrack.errlog) { fclose(httrack.errlog); httrack.errlog=NULL; }
  2264.     }  
  2265.     
  2266.     // DΘbuggage des en tΩtes
  2267.     if (_DEBUG_HEAD) {
  2268.       if (ioinfo) {
  2269.         fclose(ioinfo);
  2270.       }
  2271.     }
  2272.     
  2273.     // supprimer lock
  2274.     remove(n_lock);
  2275.   }
  2276.   
  2277.   if (x_argvblk)
  2278.     freet(x_argvblk);
  2279.  
  2280. #if HTS_WIN
  2281. #if HTS_ANALYSTE!=2
  2282. //  WSACleanup();    // ** non en cas de thread tjs prΘsent!..
  2283. #endif
  2284. #endif
  2285. #ifdef HTS_TRACE_MALLOC
  2286.   hts_freeall();
  2287. #endif
  2288.  
  2289.   printf("Thanks for using HTTrack!\n");
  2290.   io_flush;
  2291.   htsmain_free();
  2292.   return 0;    // OK
  2293. }
  2294.  
  2295.  
  2296. // main() subroutines
  2297.  
  2298. // vΘrifier chemin path
  2299. int check_path(char* s,char* defaultname) {
  2300.   int i;
  2301.   int return_value=0;
  2302.  
  2303.   // Replace name: ~/mywebsites/# -> /home/foo/mywebsites/#
  2304.   expand_home(s);
  2305.   for(i=0;i<(int) strlen(s);i++)    // conversion \ -> /
  2306.     if (s[i]=='\\')
  2307.       s[i]='/';
  2308.   
  2309.   // remove ending /
  2310.   if (strnotempty(s))
  2311.   if (s[strlen(s)-1]=='/')
  2312.     s[strlen(s)-1]='\0';
  2313.  
  2314.    // Replace name: /home/foo/mywebsites/# -> /home/foo/mywebsites/wonderfulsite
  2315.   if (strnotempty(s)) {
  2316.     if (s[(i=strlen(s))-1]=='#') {
  2317.       if (strnotempty((defaultname?defaultname:""))) {
  2318.         char tempo[HTS_URLMAXSIZE*2];
  2319.         char* a=strchr(defaultname,'#');      // we never know..
  2320.         if (a) *a='\0';
  2321.         tempo[0]='\0';
  2322.         strncatbuff(tempo,s,i-1);
  2323.         strcatbuff(tempo,defaultname);
  2324.         strcpybuff(s,tempo);
  2325.       } else
  2326.         s[0]='\0';            // Clear path (no name/default url given)
  2327.       return_value=1;     // expanded
  2328.     }
  2329.   }
  2330.  
  2331.   // ending /
  2332.   if (strnotempty(s))
  2333.   if (s[strlen(s)-1]!='/')    // ajouter slash α la fin
  2334.     strcatbuff(s,"/");
  2335.  
  2336.   return return_value;
  2337. }
  2338.  
  2339. // dΘtermine si l'argument est une option
  2340. int cmdl_opt(char* s) {
  2341.   if (s[0]=='-') {  // c'est peut Ωtre une option
  2342.     if (strchr(s,'.')!=NULL)
  2343.       return 0;    // sans doute un -www.truc.fr (note: -www n'est pas compris)
  2344.     else if (strchr(s,'/')!=NULL)
  2345.       return 0;    // idem, -*cgi-bin/
  2346.     else if (strchr(s,'*')!=NULL)
  2347.       return 0;    // joker, idem
  2348.     else
  2349.       return 1;
  2350.   } else return 0;
  2351. }
  2352.  
  2353.